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 "bridge.h"
00021 #include "town.h"
00022 #include "newgrf_engine.h"
00023 #include "newgrf_text.h"
00024 #include "fontcache.h"
00025 #include "currency.h"
00026 #include "landscape.h"
00027 #include "newgrf.h"
00028 #include "newgrf_cargo.h"
00029 #include "newgrf_house.h"
00030 #include "newgrf_sound.h"
00031 #include "newgrf_station.h"
00032 #include "industrytype.h"
00033 #include "newgrf_canal.h"
00034 #include "newgrf_townname.h"
00035 #include "newgrf_industries.h"
00036 #include "newgrf_airporttiles.h"
00037 #include "newgrf_airport.h"
00038 #include "newgrf_object.h"
00039 #include "rev.h"
00040 #include "fios.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 "smallmap_gui.h"
00047 #include "genworld.h"
00048 #include "gui.h"
00049 #include "vehicle_func.h"
00050 #include "language.h"
00051 #include "vehicle_base.h"
00052
00053 #include "table/strings.h"
00054 #include "table/build_industry.h"
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static int _skip_sprites;
00067 static uint _file_index;
00068
00069 static SmallVector<GRFFile *, 16> _grf_files;
00070
00071 static GRFFile *_cur_grffile;
00072 static SpriteID _cur_spriteid;
00073 static GrfLoadingStage _cur_stage;
00074 static uint32 _nfo_line;
00075
00076 static GRFConfig *_cur_grfconfig;
00077
00078
00079 static byte _misc_grf_features = 0;
00080
00081
00082 static uint32 _ttdpatch_flags[8];
00083
00084
00085 GRFLoadedFeatures _loaded_newgrf_features;
00086
00087 enum GrfDataType {
00088 GDT_SOUND,
00089 };
00090
00091 static byte _grf_data_blocks;
00092 static GrfDataType _grf_data_type;
00093
00094 class OTTDByteReaderSignal { };
00095
00096 class ByteReader {
00097 protected:
00098 byte *data;
00099 byte *end;
00100
00101 public:
00102 ByteReader(byte *data, byte *end) : data(data), end(end) { }
00103
00104 FORCEINLINE byte ReadByte()
00105 {
00106 if (data < end) return *(data)++;
00107 throw OTTDByteReaderSignal();
00108 }
00109
00110 uint16 ReadWord()
00111 {
00112 uint16 val = ReadByte();
00113 return val | (ReadByte() << 8);
00114 }
00115
00116 uint16 ReadExtendedByte()
00117 {
00118 uint16 val = ReadByte();
00119 return val == 0xFF ? ReadWord() : val;
00120 }
00121
00122 uint32 ReadDWord()
00123 {
00124 uint32 val = ReadWord();
00125 return val | (ReadWord() << 16);
00126 }
00127
00128 uint32 ReadVarSize(byte size)
00129 {
00130 switch (size) {
00131 case 1: return ReadByte();
00132 case 2: return ReadWord();
00133 case 4: return ReadDWord();
00134 default:
00135 NOT_REACHED();
00136 return 0;
00137 }
00138 }
00139
00140 const char *ReadString()
00141 {
00142 char *string = reinterpret_cast<char *>(data);
00143 size_t string_length = ttd_strnlen(string, Remaining());
00144
00145 if (string_length == Remaining()) {
00146
00147 string[string_length - 1] = '\0';
00148 grfmsg(7, "String was not terminated with a zero byte.");
00149 } else {
00150
00151 string_length++;
00152 }
00153 Skip(string_length);
00154
00155 return string;
00156 }
00157
00158 FORCEINLINE size_t Remaining() const
00159 {
00160 return end - data;
00161 }
00162
00163 FORCEINLINE bool HasData(size_t count = 1) const
00164 {
00165 return data + count <= end;
00166 }
00167
00168 FORCEINLINE byte *Data()
00169 {
00170 return data;
00171 }
00172
00173 FORCEINLINE void Skip(size_t len)
00174 {
00175 data += len;
00176
00177
00178 if (data > end) throw OTTDByteReaderSignal();
00179 }
00180 };
00181
00182 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
00183
00184 static const uint MAX_STATIONS = 256;
00185
00186
00187 struct GRFTempEngineData {
00188 uint16 cargo_allowed;
00189 uint16 cargo_disallowed;
00190 RailTypeLabel railtypelabel;
00191 const GRFFile *refitmask_grf;
00192 bool refitmask_valid;
00193 bool prop27_set;
00194 uint8 rv_max_speed;
00195 };
00196
00197 static GRFTempEngineData *_gted;
00198
00199
00200
00201
00202 static uint32 _grm_engines[256];
00203
00204
00205 static uint32 _grm_cargos[NUM_CARGO * 2];
00206
00207 struct GRFLocation {
00208 uint32 grfid;
00209 uint32 nfoline;
00210
00211 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
00212
00213 bool operator<(const GRFLocation &other) const
00214 {
00215 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
00216 }
00217
00218 bool operator == (const GRFLocation &other) const
00219 {
00220 return this->grfid == other.grfid && this->nfoline == other.nfoline;
00221 }
00222 };
00223
00224 static std::map<GRFLocation, SpriteID> _grm_sprites;
00225 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
00226 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
00227
00238 void CDECL grfmsg(int severity, const char *str, ...)
00239 {
00240 char buf[1024];
00241 va_list va;
00242
00243 va_start(va, str);
00244 vsnprintf(buf, sizeof(buf), str, va);
00245 va_end(va);
00246
00247 DEBUG(grf, severity, "[%s:%d] %s", _cur_grfconfig->filename, _nfo_line, buf);
00248 }
00249
00250 static GRFFile *GetFileByGRFID(uint32 grfid)
00251 {
00252 const GRFFile * const *end = _grf_files.End();
00253 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00254 if ((*file)->grfid == grfid) return *file;
00255 }
00256 return NULL;
00257 }
00258
00259 static GRFFile *GetFileByFilename(const char *filename)
00260 {
00261 const GRFFile * const *end = _grf_files.End();
00262 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00263 if (strcmp((*file)->filename, filename) == 0) return *file;
00264 }
00265 return NULL;
00266 }
00267
00269 static void ClearTemporaryNewGRFData(GRFFile *gf)
00270 {
00271
00272 for (GRFLabel *l = gf->label; l != NULL;) {
00273 GRFLabel *l2 = l->next;
00274 free(l);
00275 l = l2;
00276 }
00277 gf->label = NULL;
00278
00279
00280 free(gf->spritegroups);
00281 gf->spritegroups = NULL;
00282 gf->spritegroups_count = 0;
00283 }
00284
00291 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
00292 {
00293 GRFFile *file;
00294 if (config != NULL) {
00295 file = GetFileByGRFID(config->ident.grfid);
00296 } else {
00297 config = _cur_grfconfig;
00298 file = _cur_grffile;
00299 }
00300
00301 config->status = GCS_DISABLED;
00302 if (file != NULL) ClearTemporaryNewGRFData(file);
00303 if (config == _cur_grfconfig) _skip_sprites = -1;
00304
00305 if (message != STR_NULL) {
00306 delete config->error;
00307 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
00308 }
00309
00310 return config->error;
00311 }
00312
00313
00314 typedef std::map<StringID *, uint32> StringIDToGRFIDMapping;
00315 static StringIDToGRFIDMapping _string_to_grf_mapping;
00316
00324 StringID MapGRFStringID(uint32 grfid, StringID str)
00325 {
00326
00327
00328
00329
00330 switch (GB(str, 8, 8)) {
00331 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
00332 case 0xDC:
00333 return GetGRFStringID(grfid, str);
00334
00335 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
00336
00337
00338 return GetGRFStringID(grfid, str - 0x400);
00339
00340 default: break;
00341 }
00342
00343 return TTDPStringIDToOTTDStringIDMapping(str);
00344 }
00345
00346 static std::map<uint32, uint32> _grf_id_overrides;
00347
00348 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
00349 {
00350 _grf_id_overrides[source_grfid] = target_grfid;
00351 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
00352 }
00353
00362 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
00363 {
00364
00365
00366 uint32 scope_grfid = INVALID_GRFID;
00367 if (_settings_game.vehicle.dynamic_engines) {
00368
00369 scope_grfid = file->grfid;
00370 uint32 override = _grf_id_overrides[file->grfid];
00371 if (override != 0) {
00372 scope_grfid = override;
00373 const GRFFile *grf_match = GetFileByGRFID(override);
00374 if (grf_match == NULL) {
00375 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
00376 } else {
00377 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
00378 }
00379 }
00380
00381
00382 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
00383 if (engine != INVALID_ENGINE) {
00384 Engine *e = Engine::Get(engine);
00385 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
00386 return e;
00387 }
00388 }
00389
00390
00391 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
00392 if (engine != INVALID_ENGINE) {
00393 Engine *e = Engine::Get(engine);
00394
00395 if (e->grf_prop.grffile == NULL) {
00396 e->grf_prop.grffile = file;
00397 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00398 }
00399
00400
00401 if (!static_access) {
00402 EngineIDMapping *eid = _engine_mngr.Get(engine);
00403 eid->grfid = scope_grfid;
00404 }
00405
00406 return e;
00407 }
00408
00409 if (static_access) return NULL;
00410
00411 if (!Engine::CanAllocateItem()) {
00412 grfmsg(0, "Can't allocate any more engines");
00413 return NULL;
00414 }
00415
00416 size_t engine_pool_size = Engine::GetPoolSize();
00417
00418
00419 Engine *e = new Engine(type, internal_id);
00420 e->grf_prop.grffile = file;
00421
00422
00423 assert(_engine_mngr.Length() == e->index);
00424 EngineIDMapping *eid = _engine_mngr.Append();
00425 eid->type = type;
00426 eid->grfid = scope_grfid;
00427 eid->internal_id = internal_id;
00428 eid->substitute_id = min(internal_id, _engine_counts[type]);
00429
00430 if (engine_pool_size != Engine::GetPoolSize()) {
00431
00432 _gted = ReallocT(_gted, Engine::GetPoolSize());
00433
00434
00435 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
00436 memset(_gted + engine_pool_size, 0, len);
00437 }
00438 if (type == VEH_TRAIN) {
00439 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
00440 }
00441
00442 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00443
00444 return e;
00445 }
00446
00447 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
00448 {
00449 uint32 scope_grfid = INVALID_GRFID;
00450 if (_settings_game.vehicle.dynamic_engines) {
00451 scope_grfid = file->grfid;
00452 uint32 override = _grf_id_overrides[file->grfid];
00453 if (override != 0) scope_grfid = override;
00454 }
00455
00456 return _engine_mngr.GetID(type, internal_id, scope_grfid);
00457 }
00458
00463 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
00464 {
00465 if (HasBit(grf_sprite->pal, 14)) {
00466 ClrBit(grf_sprite->pal, 14);
00467 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
00468 }
00469
00470 if (HasBit(grf_sprite->sprite, 14)) {
00471 ClrBit(grf_sprite->sprite, 14);
00472 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
00473 }
00474
00475 if (HasBit(grf_sprite->sprite, 15)) {
00476 ClrBit(grf_sprite->sprite, 15);
00477 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
00478 }
00479 }
00480
00491 static void ReadSpriteLayoutSprite(ByteReader *buf, bool invert_action1_flag, uint action1_offset, uint action1_pitch, uint action1_max, PalSpriteID *grf_sprite)
00492 {
00493 grf_sprite->sprite = buf->ReadWord();
00494 grf_sprite->pal = buf->ReadWord();
00495
00496 MapSpriteMappingRecolour(grf_sprite);
00497
00498 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
00499 ClrBit(grf_sprite->pal, 15);
00500 if (custom_sprite) {
00501
00502 uint index = GB(grf_sprite->sprite, 0, 14);
00503 if (action1_pitch == 0 || index >= action1_max) {
00504 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
00505 grf_sprite->sprite = SPR_IMG_QUERY;
00506 grf_sprite->pal = PAL_NONE;
00507 } else {
00508 SpriteID sprite = action1_offset + index * action1_pitch;
00509 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
00510 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
00511 }
00512 }
00513 }
00514
00522 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
00523 {
00524
00525 if (base_pointer == 0) {
00526 *index = INVALID_PRICE;
00527 return;
00528 }
00529
00530 static const uint32 start = 0x4B34;
00531 static const uint32 size = 6;
00532
00533 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
00534 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
00535 return;
00536 }
00537
00538 *index = (Price)((base_pointer - start) / size);
00539 }
00540
00541 enum ChangeInfoResult {
00542 CIR_SUCCESS,
00543 CIR_UNHANDLED,
00544 CIR_UNKNOWN,
00545 CIR_INVALID_ID,
00546 };
00547
00548 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
00549
00550 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
00551 {
00552 switch (prop) {
00553 case 0x00:
00554 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00555 break;
00556
00557 case 0x02:
00558 ei->decay_speed = buf->ReadByte();
00559 break;
00560
00561 case 0x03:
00562 ei->lifelength = buf->ReadByte();
00563 break;
00564
00565 case 0x04:
00566 ei->base_life = buf->ReadByte();
00567 break;
00568
00569 case 0x06:
00570 ei->climates = buf->ReadByte();
00571 break;
00572
00573 case 0x07:
00574
00575 ei->load_amount = buf->ReadByte();
00576 break;
00577
00578 default:
00579 return CIR_UNKNOWN;
00580 }
00581
00582 return CIR_SUCCESS;
00583 }
00584
00585 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00586 {
00587 ChangeInfoResult ret = CIR_SUCCESS;
00588
00589 for (int i = 0; i < numinfo; i++) {
00590 Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i);
00591 if (e == NULL) return CIR_INVALID_ID;
00592
00593 EngineInfo *ei = &e->info;
00594 RailVehicleInfo *rvi = &e->u.rail;
00595
00596 switch (prop) {
00597 case 0x05: {
00598 uint8 tracktype = buf->ReadByte();
00599
00600 if (tracktype < _cur_grffile->railtype_max) {
00601 _gted[e->index].railtypelabel = _cur_grffile->railtype_list[tracktype];
00602 break;
00603 }
00604
00605 switch (tracktype) {
00606 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
00607 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
00608 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
00609 default:
00610 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
00611 break;
00612 }
00613 break;
00614 }
00615
00616 case 0x08:
00617
00618
00619 rvi->ai_passenger_only = buf->ReadByte();
00620 break;
00621
00622 case PROP_TRAIN_SPEED: {
00623 uint16 speed = buf->ReadWord();
00624 if (speed == 0xFFFF) speed = 0;
00625
00626 rvi->max_speed = speed;
00627 break;
00628 }
00629
00630 case PROP_TRAIN_POWER:
00631 rvi->power = buf->ReadWord();
00632
00633
00634 if (rvi->power != 0) {
00635 if (rvi->railveh_type == RAILVEH_WAGON) {
00636 rvi->railveh_type = RAILVEH_SINGLEHEAD;
00637 }
00638 } else {
00639 rvi->railveh_type = RAILVEH_WAGON;
00640 }
00641 break;
00642
00643 case PROP_TRAIN_RUNNING_COST_FACTOR:
00644 rvi->running_cost = buf->ReadByte();
00645 break;
00646
00647 case 0x0E:
00648 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
00649 break;
00650
00651 case 0x12: {
00652 uint8 spriteid = buf->ReadByte();
00653
00654
00655
00656 if (spriteid < 0xFD) spriteid >>= 1;
00657
00658 rvi->image_index = spriteid;
00659 break;
00660 }
00661
00662 case 0x13: {
00663 uint8 dual = buf->ReadByte();
00664
00665 if (dual != 0) {
00666 rvi->railveh_type = RAILVEH_MULTIHEAD;
00667 } else {
00668 rvi->railveh_type = rvi->power == 0 ?
00669 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
00670 }
00671 break;
00672 }
00673
00674 case PROP_TRAIN_CARGO_CAPACITY:
00675 rvi->capacity = buf->ReadByte();
00676 break;
00677
00678 case 0x15: {
00679 uint8 ctype = buf->ReadByte();
00680
00681 if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
00682 ei->cargo_type = ctype;
00683 } else if (ctype == 0xFF) {
00684
00685 ei->cargo_type = CT_INVALID;
00686 } else {
00687 ei->cargo_type = CT_INVALID;
00688 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
00689 }
00690 break;
00691 }
00692
00693 case PROP_TRAIN_WEIGHT:
00694 SB(rvi->weight, 0, 8, buf->ReadByte());
00695 break;
00696
00697 case PROP_TRAIN_COST_FACTOR:
00698 rvi->cost_factor = buf->ReadByte();
00699 break;
00700
00701 case 0x18:
00702 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
00703 buf->ReadByte();
00704 break;
00705
00706 case 0x19: {
00707
00708
00709
00710
00711
00712
00713
00714 uint8 traction = buf->ReadByte();
00715 EngineClass engclass;
00716
00717 if (traction <= 0x07) {
00718 engclass = EC_STEAM;
00719 } else if (traction <= 0x27) {
00720 engclass = EC_DIESEL;
00721 } else if (traction <= 0x31) {
00722 engclass = EC_ELECTRIC;
00723 } else if (traction <= 0x37) {
00724 engclass = EC_MONORAIL;
00725 } else if (traction <= 0x41) {
00726 engclass = EC_MAGLEV;
00727 } else {
00728 break;
00729 }
00730
00731 if (_cur_grffile->railtype_max == 0) {
00732
00733
00734 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
00735 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
00736 }
00737
00738 rvi->engclass = engclass;
00739 break;
00740 }
00741
00742 case 0x1A:
00743 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
00744 break;
00745
00746 case 0x1B:
00747 rvi->pow_wag_power = buf->ReadWord();
00748 break;
00749
00750 case 0x1C:
00751 ei->refit_cost = buf->ReadByte();
00752 break;
00753
00754 case 0x1D:
00755 ei->refit_mask = buf->ReadDWord();
00756 _gted[e->index].refitmask_valid = true;
00757 _gted[e->index].refitmask_grf = _cur_grffile;
00758 break;
00759
00760 case 0x1E:
00761 ei->callback_mask = buf->ReadByte();
00762 break;
00763
00764 case PROP_TRAIN_TRACTIVE_EFFORT:
00765 rvi->tractive_effort = buf->ReadByte();
00766 break;
00767
00768 case 0x20:
00769 rvi->air_drag = buf->ReadByte();
00770 break;
00771
00772 case 0x21:
00773 rvi->shorten_factor = buf->ReadByte();
00774 break;
00775
00776 case 0x22:
00777 rvi->visual_effect = buf->ReadByte();
00778
00779
00780 if (rvi->visual_effect == VE_DEFAULT) {
00781 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
00782 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
00783 }
00784 break;
00785
00786 case 0x23:
00787 rvi->pow_wag_weight = buf->ReadByte();
00788 break;
00789
00790 case 0x24: {
00791 byte weight = buf->ReadByte();
00792
00793 if (weight > 4) {
00794 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
00795 } else {
00796 SB(rvi->weight, 8, 8, weight);
00797 }
00798 break;
00799 }
00800
00801 case PROP_TRAIN_USER_DATA:
00802 rvi->user_def_data = buf->ReadByte();
00803 break;
00804
00805 case 0x26:
00806 ei->retire_early = buf->ReadByte();
00807 break;
00808
00809 case 0x27:
00810 ei->misc_flags = buf->ReadByte();
00811 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00812 _gted[e->index].prop27_set = true;
00813 break;
00814
00815 case 0x28:
00816 _gted[e->index].cargo_allowed = buf->ReadWord();
00817 _gted[e->index].refitmask_valid = true;
00818 break;
00819
00820 case 0x29:
00821 _gted[e->index].cargo_disallowed = buf->ReadWord();
00822 _gted[e->index].refitmask_valid = true;
00823 break;
00824
00825 case 0x2A:
00826 ei->base_intro = buf->ReadDWord();
00827 break;
00828
00829 default:
00830 ret = CommonVehicleChangeInfo(ei, prop, buf);
00831 break;
00832 }
00833 }
00834
00835 return ret;
00836 }
00837
00838 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00839 {
00840 ChangeInfoResult ret = CIR_SUCCESS;
00841
00842 for (int i = 0; i < numinfo; i++) {
00843 Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i);
00844 if (e == NULL) return CIR_INVALID_ID;
00845
00846 EngineInfo *ei = &e->info;
00847 RoadVehicleInfo *rvi = &e->u.road;
00848
00849 switch (prop) {
00850 case 0x08:
00851 rvi->max_speed = buf->ReadByte();
00852 break;
00853
00854 case PROP_ROADVEH_RUNNING_COST_FACTOR:
00855 rvi->running_cost = buf->ReadByte();
00856 break;
00857
00858 case 0x0A:
00859 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
00860 break;
00861
00862 case 0x0E: {
00863 uint8 spriteid = buf->ReadByte();
00864
00865
00866 if (spriteid == 0xFF) spriteid = 0xFD;
00867
00868 if (spriteid < 0xFD) spriteid >>= 1;
00869
00870 rvi->image_index = spriteid;
00871 break;
00872 }
00873
00874 case PROP_ROADVEH_CARGO_CAPACITY:
00875 rvi->capacity = buf->ReadByte();
00876 break;
00877
00878 case 0x10: {
00879 uint8 cargo = buf->ReadByte();
00880
00881 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
00882 ei->cargo_type = cargo;
00883 } else if (cargo == 0xFF) {
00884 ei->cargo_type = CT_INVALID;
00885 } else {
00886 ei->cargo_type = CT_INVALID;
00887 grfmsg(2, "RoadVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
00888 }
00889 break;
00890 }
00891
00892 case PROP_ROADVEH_COST_FACTOR:
00893 rvi->cost_factor = buf->ReadByte();
00894 break;
00895
00896 case 0x12:
00897 rvi->sfx = buf->ReadByte();
00898 break;
00899
00900 case PROP_ROADVEH_POWER:
00901 rvi->power = buf->ReadByte();
00902 break;
00903
00904 case PROP_ROADVEH_WEIGHT:
00905 rvi->weight = buf->ReadByte();
00906 break;
00907
00908 case PROP_ROADVEH_SPEED:
00909 _gted[e->index].rv_max_speed = buf->ReadByte();
00910 break;
00911
00912 case 0x16:
00913 ei->refit_mask = buf->ReadDWord();
00914 _gted[e->index].refitmask_valid = true;
00915 _gted[e->index].refitmask_grf = _cur_grffile;
00916 break;
00917
00918 case 0x17:
00919 ei->callback_mask = buf->ReadByte();
00920 break;
00921
00922 case PROP_ROADVEH_TRACTIVE_EFFORT:
00923 rvi->tractive_effort = buf->ReadByte();
00924 break;
00925
00926 case 0x19:
00927 rvi->air_drag = buf->ReadByte();
00928 break;
00929
00930 case 0x1A:
00931 ei->refit_cost = buf->ReadByte();
00932 break;
00933
00934 case 0x1B:
00935 ei->retire_early = buf->ReadByte();
00936 break;
00937
00938 case 0x1C:
00939 ei->misc_flags = buf->ReadByte();
00940 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00941 break;
00942
00943 case 0x1D:
00944 _gted[e->index].cargo_allowed = buf->ReadWord();
00945 _gted[e->index].refitmask_valid = true;
00946 break;
00947
00948 case 0x1E:
00949 _gted[e->index].cargo_disallowed = buf->ReadWord();
00950 _gted[e->index].refitmask_valid = true;
00951 break;
00952
00953 case 0x1F:
00954 ei->base_intro = buf->ReadDWord();
00955 break;
00956
00957 case 0x20:
00958 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
00959 break;
00960
00961 case 0x21:
00962 rvi->visual_effect = buf->ReadByte();
00963
00964
00965 if (rvi->visual_effect == VE_DEFAULT) {
00966 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
00967 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
00968 }
00969 break;
00970
00971 default:
00972 ret = CommonVehicleChangeInfo(ei, prop, buf);
00973 break;
00974 }
00975 }
00976
00977 return ret;
00978 }
00979
00980 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00981 {
00982 ChangeInfoResult ret = CIR_SUCCESS;
00983
00984 for (int i = 0; i < numinfo; i++) {
00985 Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i);
00986 if (e == NULL) return CIR_INVALID_ID;
00987
00988 EngineInfo *ei = &e->info;
00989 ShipVehicleInfo *svi = &e->u.ship;
00990
00991 switch (prop) {
00992 case 0x08: {
00993 uint8 spriteid = buf->ReadByte();
00994
00995
00996 if (spriteid == 0xFF) spriteid = 0xFD;
00997
00998 if (spriteid < 0xFD) spriteid >>= 1;
00999
01000 svi->image_index = spriteid;
01001 break;
01002 }
01003
01004 case 0x09:
01005 svi->old_refittable = (buf->ReadByte() != 0);
01006 break;
01007
01008 case PROP_SHIP_COST_FACTOR:
01009 svi->cost_factor = buf->ReadByte();
01010 break;
01011
01012 case PROP_SHIP_SPEED:
01013 svi->max_speed = buf->ReadByte();
01014 break;
01015
01016 case 0x0C: {
01017 uint8 cargo = buf->ReadByte();
01018
01019 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
01020 ei->cargo_type = cargo;
01021 } else if (cargo == 0xFF) {
01022 ei->cargo_type = CT_INVALID;
01023 } else {
01024 ei->cargo_type = CT_INVALID;
01025 grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
01026 }
01027 break;
01028 }
01029
01030 case PROP_SHIP_CARGO_CAPACITY:
01031 svi->capacity = buf->ReadWord();
01032 break;
01033
01034 case PROP_SHIP_RUNNING_COST_FACTOR:
01035 svi->running_cost = buf->ReadByte();
01036 break;
01037
01038 case 0x10:
01039 svi->sfx = buf->ReadByte();
01040 break;
01041
01042 case 0x11:
01043 ei->refit_mask = buf->ReadDWord();
01044 _gted[e->index].refitmask_valid = true;
01045 _gted[e->index].refitmask_grf = _cur_grffile;
01046 break;
01047
01048 case 0x12:
01049 ei->callback_mask = buf->ReadByte();
01050 break;
01051
01052 case 0x13:
01053 ei->refit_cost = buf->ReadByte();
01054 break;
01055
01056 case 0x14:
01057 case 0x15:
01059 buf->ReadByte();
01060 ret = CIR_UNHANDLED;
01061 break;
01062
01063 case 0x16:
01064 ei->retire_early = buf->ReadByte();
01065 break;
01066
01067 case 0x17:
01068 ei->misc_flags = buf->ReadByte();
01069 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01070 break;
01071
01072 case 0x18:
01073 _gted[e->index].cargo_allowed = buf->ReadWord();
01074 _gted[e->index].refitmask_valid = true;
01075 break;
01076
01077 case 0x19:
01078 _gted[e->index].cargo_disallowed = buf->ReadWord();
01079 _gted[e->index].refitmask_valid = true;
01080 break;
01081
01082 case 0x1A:
01083 ei->base_intro = buf->ReadDWord();
01084 break;
01085
01086 case 0x1B:
01087 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01088 break;
01089
01090 case 0x1C:
01091 svi->visual_effect = buf->ReadByte();
01092
01093
01094 if (svi->visual_effect == VE_DEFAULT) {
01095 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
01096 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
01097 }
01098 break;
01099
01100 default:
01101 ret = CommonVehicleChangeInfo(ei, prop, buf);
01102 break;
01103 }
01104 }
01105
01106 return ret;
01107 }
01108
01109 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
01110 {
01111 ChangeInfoResult ret = CIR_SUCCESS;
01112
01113 for (int i = 0; i < numinfo; i++) {
01114 Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i);
01115 if (e == NULL) return CIR_INVALID_ID;
01116
01117 EngineInfo *ei = &e->info;
01118 AircraftVehicleInfo *avi = &e->u.air;
01119
01120 switch (prop) {
01121 case 0x08: {
01122 uint8 spriteid = buf->ReadByte();
01123
01124
01125 if (spriteid == 0xFF) spriteid = 0xFD;
01126
01127 if (spriteid < 0xFD) spriteid >>= 1;
01128
01129 avi->image_index = spriteid;
01130 break;
01131 }
01132
01133 case 0x09:
01134 if (buf->ReadByte() == 0) {
01135 avi->subtype = AIR_HELI;
01136 } else {
01137 SB(avi->subtype, 0, 1, 1);
01138 }
01139 break;
01140
01141 case 0x0A:
01142 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
01143 break;
01144
01145 case PROP_AIRCRAFT_COST_FACTOR:
01146 avi->cost_factor = buf->ReadByte();
01147 break;
01148
01149 case PROP_AIRCRAFT_SPEED:
01150 avi->max_speed = (buf->ReadByte() * 128) / 10;
01151 break;
01152
01153 case 0x0D:
01154 avi->acceleration = (buf->ReadByte() * 128) / 10;
01155 break;
01156
01157 case PROP_AIRCRAFT_RUNNING_COST_FACTOR:
01158 avi->running_cost = buf->ReadByte();
01159 break;
01160
01161 case PROP_AIRCRAFT_PASSENGER_CAPACITY:
01162 avi->passenger_capacity = buf->ReadWord();
01163 break;
01164
01165 case PROP_AIRCRAFT_MAIL_CAPACITY:
01166 avi->mail_capacity = buf->ReadByte();
01167 break;
01168
01169 case 0x12:
01170 avi->sfx = buf->ReadByte();
01171 break;
01172
01173 case 0x13:
01174 ei->refit_mask = buf->ReadDWord();
01175 _gted[e->index].refitmask_valid = true;
01176 _gted[e->index].refitmask_grf = _cur_grffile;
01177 break;
01178
01179 case 0x14:
01180 ei->callback_mask = buf->ReadByte();
01181 break;
01182
01183 case 0x15:
01184 ei->refit_cost = buf->ReadByte();
01185 break;
01186
01187 case 0x16:
01188 ei->retire_early = buf->ReadByte();
01189 break;
01190
01191 case 0x17:
01192 ei->misc_flags = buf->ReadByte();
01193 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01194 break;
01195
01196 case 0x18:
01197 _gted[e->index].cargo_allowed = buf->ReadWord();
01198 _gted[e->index].refitmask_valid = true;
01199 break;
01200
01201 case 0x19:
01202 _gted[e->index].cargo_disallowed = buf->ReadWord();
01203 _gted[e->index].refitmask_valid = true;
01204 break;
01205
01206 case 0x1A:
01207 ei->base_intro = buf->ReadDWord();
01208 break;
01209
01210 case 0x1B:
01211 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01212 break;
01213
01214 default:
01215 ret = CommonVehicleChangeInfo(ei, prop, buf);
01216 break;
01217 }
01218 }
01219
01220 return ret;
01221 }
01222
01223 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
01224 {
01225 ChangeInfoResult ret = CIR_SUCCESS;
01226
01227 if (stid + numinfo > MAX_STATIONS) {
01228 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
01229 return CIR_INVALID_ID;
01230 }
01231
01232
01233 if (_cur_grffile->stations == NULL) _cur_grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
01234
01235 for (int i = 0; i < numinfo; i++) {
01236 StationSpec *statspec = _cur_grffile->stations[stid + i];
01237
01238
01239 if (statspec == NULL && prop != 0x08) {
01240 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
01241 return CIR_INVALID_ID;
01242 }
01243
01244 switch (prop) {
01245 case 0x08: {
01246 StationSpec **spec = &_cur_grffile->stations[stid + i];
01247
01248
01249 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
01250
01251
01252 uint32 classid = buf->ReadDWord();
01253 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
01254 break;
01255 }
01256
01257 case 0x09:
01258 delete[] statspec->renderdata;
01259
01260 statspec->tiles = buf->ReadExtendedByte();
01261 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01262
01263 for (uint t = 0; t < statspec->tiles; t++) {
01264 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
01265
01266 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
01267 buf->Skip(4);
01268 extern const DrawTileSprites _station_display_datas_rail[8];
01269 dts->Clone(&_station_display_datas_rail[t % 8]);
01270 continue;
01271 }
01272
01273 ReadSpriteLayoutSprite(buf, false, 0, 1, UINT_MAX, &dts->ground);
01274
01275 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
01276 tmp_layout.Clear();
01277 for (;;) {
01278
01279 DrawTileSeqStruct *dtss = tmp_layout.Append();
01280 MemSetT(dtss, 0);
01281
01282 dtss->delta_x = buf->ReadByte();
01283 if (dtss->IsTerminator()) break;
01284 dtss->delta_y = buf->ReadByte();
01285 dtss->delta_z = buf->ReadByte();
01286 dtss->size_x = buf->ReadByte();
01287 dtss->size_y = buf->ReadByte();
01288 dtss->size_z = buf->ReadByte();
01289
01290 ReadSpriteLayoutSprite(buf, true, 0, 1, UINT_MAX, &dtss->image);
01291 }
01292 dts->Clone(tmp_layout.Begin());
01293 }
01294 break;
01295
01296 case 0x0A: {
01297 byte srcid = buf->ReadByte();
01298 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01299
01300 if (srcstatspec == NULL) {
01301 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
01302 continue;
01303 }
01304
01305 delete[] statspec->renderdata;
01306
01307 statspec->tiles = srcstatspec->tiles;
01308 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01309 for (uint t = 0; t < statspec->tiles; t++) {
01310 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
01311 }
01312 break;
01313 }
01314
01315 case 0x0B:
01316 statspec->callback_mask = buf->ReadByte();
01317 break;
01318
01319 case 0x0C:
01320 statspec->disallowed_platforms = buf->ReadByte();
01321 break;
01322
01323 case 0x0D:
01324 statspec->disallowed_lengths = buf->ReadByte();
01325 break;
01326
01327 case 0x0E:
01328 statspec->copied_layouts = false;
01329
01330 while (buf->HasData()) {
01331 byte length = buf->ReadByte();
01332 byte number = buf->ReadByte();
01333 StationLayout layout;
01334 uint l, p;
01335
01336 if (length == 0 || number == 0) break;
01337
01338 if (length > statspec->lengths) {
01339 statspec->platforms = ReallocT(statspec->platforms, length);
01340 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
01341
01342 statspec->layouts = ReallocT(statspec->layouts, length);
01343 memset(statspec->layouts + statspec->lengths, 0,
01344 (length - statspec->lengths) * sizeof(*statspec->layouts));
01345
01346 statspec->lengths = length;
01347 }
01348 l = length - 1;
01349
01350 if (number > statspec->platforms[l]) {
01351 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
01352
01353 memset(statspec->layouts[l] + statspec->platforms[l], 0,
01354 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
01355
01356 statspec->platforms[l] = number;
01357 }
01358
01359 p = 0;
01360 layout = MallocT<byte>(length * number);
01361 try {
01362 for (l = 0; l < length; l++) {
01363 for (p = 0; p < number; p++) {
01364 layout[l * number + p] = buf->ReadByte();
01365 }
01366 }
01367 } catch (...) {
01368 free(layout);
01369 throw;
01370 }
01371
01372 l--;
01373 p--;
01374 free(statspec->layouts[l][p]);
01375 statspec->layouts[l][p] = layout;
01376 }
01377 break;
01378
01379 case 0x0F: {
01380 byte srcid = buf->ReadByte();
01381 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01382
01383 if (srcstatspec == NULL) {
01384 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
01385 continue;
01386 }
01387
01388 statspec->lengths = srcstatspec->lengths;
01389 statspec->platforms = srcstatspec->platforms;
01390 statspec->layouts = srcstatspec->layouts;
01391 statspec->copied_layouts = true;
01392 break;
01393 }
01394
01395 case 0x10:
01396 statspec->cargo_threshold = buf->ReadWord();
01397 break;
01398
01399 case 0x11:
01400 statspec->pylons = buf->ReadByte();
01401 break;
01402
01403 case 0x12:
01404 statspec->cargo_triggers = buf->ReadDWord();
01405 break;
01406
01407 case 0x13:
01408 statspec->flags = buf->ReadByte();
01409 break;
01410
01411 case 0x14:
01412 statspec->wires = buf->ReadByte();
01413 break;
01414
01415 case 0x15:
01416 statspec->blocked = buf->ReadByte();
01417 break;
01418
01419 case 0x16:
01420 statspec->animation.frames = buf->ReadByte();
01421 statspec->animation.status = buf->ReadByte();
01422 break;
01423
01424 case 0x17:
01425 statspec->animation.speed = buf->ReadByte();
01426 break;
01427
01428 case 0x18:
01429 statspec->animation.triggers = buf->ReadWord();
01430 break;
01431
01432 default:
01433 ret = CIR_UNKNOWN;
01434 break;
01435 }
01436 }
01437
01438 return ret;
01439 }
01440
01441 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
01442 {
01443 ChangeInfoResult ret = CIR_SUCCESS;
01444
01445 if (id + numinfo > CF_END) {
01446 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END);
01447 return CIR_INVALID_ID;
01448 }
01449
01450 for (int i = 0; i < numinfo; i++) {
01451 WaterFeature *wf = &_water_feature[id + i];
01452
01453 switch (prop) {
01454 case 0x08:
01455 wf->callback_mask = buf->ReadByte();
01456 break;
01457
01458 case 0x09:
01459 wf->flags = buf->ReadByte();
01460 break;
01461
01462 default:
01463 ret = CIR_UNKNOWN;
01464 break;
01465 }
01466 }
01467
01468 return ret;
01469 }
01470
01471 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
01472 {
01473 ChangeInfoResult ret = CIR_SUCCESS;
01474
01475 if (brid + numinfo > MAX_BRIDGES) {
01476 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
01477 return CIR_INVALID_ID;
01478 }
01479
01480 for (int i = 0; i < numinfo; i++) {
01481 BridgeSpec *bridge = &_bridge[brid + i];
01482
01483 switch (prop) {
01484 case 0x08: {
01485
01486 byte year = buf->ReadByte();
01487 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
01488 break;
01489 }
01490
01491 case 0x09:
01492 bridge->min_length = buf->ReadByte();
01493 break;
01494
01495 case 0x0A:
01496 bridge->max_length = buf->ReadByte();
01497 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
01498 break;
01499
01500 case 0x0B:
01501 bridge->price = buf->ReadByte();
01502 break;
01503
01504 case 0x0C:
01505 bridge->speed = buf->ReadWord();
01506 break;
01507
01508 case 0x0D: {
01509 byte tableid = buf->ReadByte();
01510 byte numtables = buf->ReadByte();
01511
01512 if (bridge->sprite_table == NULL) {
01513
01514 bridge->sprite_table = CallocT<PalSpriteID*>(7);
01515 }
01516
01517 for (; numtables-- != 0; tableid++) {
01518 if (tableid >= 7) {
01519 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
01520 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
01521 continue;
01522 }
01523
01524 if (bridge->sprite_table[tableid] == NULL) {
01525 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
01526 }
01527
01528 for (byte sprite = 0; sprite < 32; sprite++) {
01529 SpriteID image = buf->ReadWord();
01530 PaletteID pal = buf->ReadWord();
01531
01532 bridge->sprite_table[tableid][sprite].sprite = image;
01533 bridge->sprite_table[tableid][sprite].pal = pal;
01534
01535 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
01536 }
01537 }
01538 break;
01539 }
01540
01541 case 0x0E:
01542 bridge->flags = buf->ReadByte();
01543 break;
01544
01545 case 0x0F:
01546 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
01547 break;
01548
01549 case 0x10: {
01550 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01551 if (newone != STR_UNDEFINED) bridge->material = newone;
01552 break;
01553 }
01554
01555 case 0x11:
01556 case 0x12: {
01557 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01558 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
01559 break;
01560 }
01561
01562 case 0x13:
01563 bridge->price = buf->ReadWord();
01564 break;
01565
01566 default:
01567 ret = CIR_UNKNOWN;
01568 break;
01569 }
01570 }
01571
01572 return ret;
01573 }
01574
01575 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
01576 {
01577 ChangeInfoResult ret = CIR_SUCCESS;
01578
01579 switch (prop) {
01580 case 0x09:
01581 case 0x0B:
01582 case 0x0C:
01583 case 0x0D:
01584 case 0x0E:
01585 case 0x0F:
01586 case 0x11:
01587 case 0x14:
01588 case 0x15:
01589 case 0x16:
01590 case 0x18:
01591 case 0x19:
01592 case 0x1A:
01593 case 0x1B:
01594 case 0x1C:
01595 case 0x1D:
01596 case 0x1F:
01597 buf->ReadByte();
01598 break;
01599
01600 case 0x0A:
01601 case 0x10:
01602 case 0x12:
01603 case 0x13:
01604 case 0x21:
01605 case 0x22:
01606 buf->ReadWord();
01607 break;
01608
01609 case 0x1E:
01610 buf->ReadDWord();
01611 break;
01612
01613 case 0x17:
01614 for (uint j = 0; j < 4; j++) buf->ReadByte();
01615 break;
01616
01617 case 0x20: {
01618 byte count = buf->ReadByte();
01619 for (byte j = 0; j < count; j++) buf->ReadByte();
01620 ret = CIR_UNHANDLED;
01621 break;
01622 }
01623
01624 default:
01625 ret = CIR_UNKNOWN;
01626 break;
01627 }
01628 return ret;
01629 }
01630
01631 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
01632 {
01633 ChangeInfoResult ret = CIR_SUCCESS;
01634
01635 if (hid + numinfo > HOUSE_MAX) {
01636 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
01637 return CIR_INVALID_ID;
01638 }
01639
01640
01641 if (_cur_grffile->housespec == NULL) {
01642 _cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
01643 }
01644
01645 for (int i = 0; i < numinfo; i++) {
01646 HouseSpec *housespec = _cur_grffile->housespec[hid + i];
01647
01648 if (prop != 0x08 && housespec == NULL) {
01649
01650 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
01651 if (cir > ret) ret = cir;
01652 continue;
01653 }
01654
01655 switch (prop) {
01656 case 0x08: {
01657 HouseSpec **house = &_cur_grffile->housespec[hid + i];
01658 byte subs_id = buf->ReadByte();
01659
01660 if (subs_id == 0xFF) {
01661
01662
01663 HouseSpec::Get(hid + i)->enabled = false;
01664 continue;
01665 } else if (subs_id >= NEW_HOUSE_OFFSET) {
01666
01667 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
01668 continue;
01669 }
01670
01671
01672 if (*house == NULL) *house = CallocT<HouseSpec>(1);
01673
01674 housespec = *house;
01675
01676 MemCpyT(housespec, HouseSpec::Get(subs_id));
01677
01678 housespec->enabled = true;
01679 housespec->grf_prop.local_id = hid + i;
01680 housespec->grf_prop.subst_id = subs_id;
01681 housespec->grf_prop.grffile = _cur_grffile;
01682 housespec->random_colour[0] = 0x04;
01683 housespec->random_colour[1] = 0x08;
01684 housespec->random_colour[2] = 0x0C;
01685 housespec->random_colour[3] = 0x06;
01686
01687
01688
01689
01690
01691 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
01692 housespec->cargo_acceptance[2] = 0;
01693 }
01694
01700 if (housespec->min_year < 1930) housespec->min_year = 1930;
01701
01702 _loaded_newgrf_features.has_newhouses = true;
01703 break;
01704 }
01705
01706 case 0x09:
01707 housespec->building_flags = (BuildingFlags)buf->ReadByte();
01708 break;
01709
01710 case 0x0A: {
01711 uint16 years = buf->ReadWord();
01712 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
01713 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
01714 break;
01715 }
01716
01717 case 0x0B:
01718 housespec->population = buf->ReadByte();
01719 break;
01720
01721 case 0x0C:
01722 housespec->mail_generation = buf->ReadByte();
01723 break;
01724
01725 case 0x0D:
01726 case 0x0E:
01727 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
01728 break;
01729
01730 case 0x0F: {
01731 int8 goods = buf->ReadByte();
01732
01733
01734
01735 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
01736 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
01737
01738
01739 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
01740
01741 housespec->accepts_cargo[2] = cid;
01742 housespec->cargo_acceptance[2] = abs(goods);
01743 break;
01744 }
01745
01746 case 0x10:
01747 housespec->remove_rating_decrease = buf->ReadWord();
01748 break;
01749
01750 case 0x11:
01751 housespec->removal_cost = buf->ReadByte();
01752 break;
01753
01754 case 0x12:
01755 housespec->building_name = buf->ReadWord();
01756 _string_to_grf_mapping[&housespec->building_name] = _cur_grffile->grfid;
01757 break;
01758
01759 case 0x13:
01760 housespec->building_availability = (HouseZones)buf->ReadWord();
01761 break;
01762
01763 case 0x14:
01764 housespec->callback_mask |= buf->ReadByte();
01765 break;
01766
01767 case 0x15: {
01768 byte override = buf->ReadByte();
01769
01770
01771 if (override >= NEW_HOUSE_OFFSET) {
01772 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
01773 continue;
01774 }
01775
01776 _house_mngr.Add(hid + i, _cur_grffile->grfid, override);
01777 break;
01778 }
01779
01780 case 0x16:
01781 housespec->processing_time = min(buf->ReadByte(), 63);
01782 break;
01783
01784 case 0x17:
01785 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
01786 break;
01787
01788 case 0x18:
01789 housespec->probability = buf->ReadByte();
01790 break;
01791
01792 case 0x19:
01793 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
01794 break;
01795
01796 case 0x1A:
01797 housespec->animation.frames = buf->ReadByte();
01798 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
01799 SB(housespec->animation.frames, 7, 1, 0);
01800 break;
01801
01802 case 0x1B:
01803 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
01804 break;
01805
01806 case 0x1C:
01807 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur_grffile->grfid);
01808 break;
01809
01810 case 0x1D:
01811 housespec->callback_mask |= (buf->ReadByte() << 8);
01812 break;
01813
01814 case 0x1E: {
01815 uint32 cargotypes = buf->ReadDWord();
01816
01817
01818 if (cargotypes == 0xFFFFFFFF) break;
01819
01820 for (uint j = 0; j < 3; j++) {
01821
01822 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
01823 CargoID cargo = GetCargoTranslation(cargo_part, _cur_grffile);
01824
01825 if (cargo == CT_INVALID) {
01826
01827 housespec->cargo_acceptance[j] = 0;
01828 } else {
01829 housespec->accepts_cargo[j] = cargo;
01830 }
01831 }
01832 break;
01833 }
01834
01835 case 0x1F:
01836 housespec->minimum_life = buf->ReadByte();
01837 break;
01838
01839 case 0x20: {
01840 byte count = buf->ReadByte();
01841 for (byte j = 0; j < count; j++) buf->ReadByte();
01842 ret = CIR_UNHANDLED;
01843 break;
01844 }
01845
01846 case 0x21:
01847 housespec->min_year = buf->ReadWord();
01848 break;
01849
01850 case 0x22:
01851 housespec->max_year = buf->ReadWord();
01852 break;
01853
01854 default:
01855 ret = CIR_UNKNOWN;
01856 break;
01857 }
01858 }
01859
01860 return ret;
01861 }
01862
01869 const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
01870 {
01871
01872 const GRFFile *grffile = GetFileByGRFID(grfid);
01873 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
01874 }
01875
01876 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01877 {
01878 ChangeInfoResult ret = CIR_SUCCESS;
01879
01880 for (int i = 0; i < numinfo; i++) {
01881 switch (prop) {
01882 case 0x08: {
01883 int factor = buf->ReadByte();
01884 uint price = gvid + i;
01885
01886 if (price < PR_END) {
01887 _cur_grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
01888 } else {
01889 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
01890 }
01891 break;
01892 }
01893
01894 case 0x09:
01895
01896
01897 buf->Skip(4);
01898 break;
01899
01900 case 0x0A: {
01901 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01902 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01903
01904 if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
01905 _currency_specs[curidx].name = newone;
01906 }
01907 break;
01908 }
01909
01910 case 0x0B: {
01911 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01912 uint32 rate = buf->ReadDWord();
01913
01914 if (curidx < NUM_CURRENCY) {
01915
01916
01917
01918 _currency_specs[curidx].rate = rate / 1000;
01919 } else {
01920 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
01921 }
01922 break;
01923 }
01924
01925 case 0x0C: {
01926 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01927 uint16 options = buf->ReadWord();
01928
01929 if (curidx < NUM_CURRENCY) {
01930 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
01931 _currency_specs[curidx].separator[1] = '\0';
01932
01933
01934 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
01935 } else {
01936 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
01937 }
01938 break;
01939 }
01940
01941 case 0x0D: {
01942 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01943 uint32 tempfix = buf->ReadDWord();
01944
01945 if (curidx < NUM_CURRENCY) {
01946 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
01947 _currency_specs[curidx].prefix[4] = 0;
01948 } else {
01949 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01950 }
01951 break;
01952 }
01953
01954 case 0x0E: {
01955 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01956 uint32 tempfix = buf->ReadDWord();
01957
01958 if (curidx < NUM_CURRENCY) {
01959 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
01960 _currency_specs[curidx].suffix[4] = 0;
01961 } else {
01962 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01963 }
01964 break;
01965 }
01966
01967 case 0x0F: {
01968 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01969 Year year_euro = buf->ReadWord();
01970
01971 if (curidx < NUM_CURRENCY) {
01972 _currency_specs[curidx].to_euro = year_euro;
01973 } else {
01974 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
01975 }
01976 break;
01977 }
01978
01979 case 0x10:
01980 if (numinfo > 1 || IsSnowLineSet()) {
01981 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
01982 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
01983 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
01984 } else {
01985 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
01986
01987 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
01988 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
01989 table[i][j] = buf->ReadByte();
01990 }
01991 }
01992 SetSnowLine(table);
01993 }
01994 break;
01995
01996 case 0x11:
01997
01998
01999 buf->Skip(8);
02000 break;
02001
02002 case 0x12:
02003
02004
02005 buf->Skip(4);
02006 break;
02007
02008 case 0x13:
02009 case 0x14:
02010 case 0x15: {
02011 uint curidx = gvid + i;
02012 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
02013 if (lang == NULL) {
02014 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
02015
02016 while (buf->ReadByte() != 0) {
02017 buf->ReadString();
02018 }
02019 break;
02020 }
02021
02022 if (_cur_grffile->language_map == NULL) _cur_grffile->language_map = new LanguageMap[MAX_LANG];
02023
02024 if (prop == 0x15) {
02025 uint plural_form = buf->ReadByte();
02026 if (plural_form >= LANGUAGE_MAX_PLURAL) {
02027 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
02028 } else {
02029 _cur_grffile->language_map[curidx].plural_form = plural_form;
02030 }
02031 break;
02032 }
02033
02034 byte newgrf_id = buf->ReadByte();
02035 while (newgrf_id != 0) {
02036 const char *name = buf->ReadString();
02037
02038
02039
02040
02041
02042 WChar c;
02043 size_t len = Utf8Decode(&c, name);
02044 if (c == NFO_UTF8_IDENTIFIER) name += len;
02045
02046 LanguageMap::Mapping map;
02047 map.newgrf_id = newgrf_id;
02048 if (prop == 0x13) {
02049 map.openttd_id = lang->GetGenderIndex(name);
02050 if (map.openttd_id >= MAX_NUM_GENDERS) {
02051 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
02052 } else {
02053 *_cur_grffile->language_map[curidx].gender_map.Append() = map;
02054 }
02055 } else {
02056 map.openttd_id = lang->GetCaseIndex(name);
02057 if (map.openttd_id >= MAX_NUM_CASES) {
02058 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
02059 } else {
02060 *_cur_grffile->language_map[curidx].case_map.Append() = map;
02061 }
02062 }
02063 newgrf_id = buf->ReadByte();
02064 }
02065 break;
02066 }
02067
02068 default:
02069 ret = CIR_UNKNOWN;
02070 break;
02071 }
02072 }
02073
02074 return ret;
02075 }
02076
02077 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
02078 {
02079 ChangeInfoResult ret = CIR_SUCCESS;
02080
02081 for (int i = 0; i < numinfo; i++) {
02082 switch (prop) {
02083 case 0x08:
02084 case 0x15:
02085 buf->ReadByte();
02086 break;
02087
02088 case 0x09: {
02089 if (i == 0) {
02090 if (gvid != 0) {
02091 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
02092 return CIR_INVALID_ID;
02093 }
02094
02095 free(_cur_grffile->cargo_list);
02096 _cur_grffile->cargo_max = numinfo;
02097 _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
02098 }
02099
02100 CargoLabel cl = buf->ReadDWord();
02101 _cur_grffile->cargo_list[i] = BSWAP32(cl);
02102 break;
02103 }
02104
02105 case 0x0A:
02106 case 0x0C:
02107 case 0x0F:
02108 buf->ReadWord();
02109 break;
02110
02111 case 0x0B:
02112 case 0x0D:
02113 case 0x0E:
02114 buf->ReadDWord();
02115 break;
02116
02117 case 0x10:
02118 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
02119 break;
02120
02121 case 0x11: {
02122 uint32 s = buf->ReadDWord();
02123 uint32 t = buf->ReadDWord();
02124 SetNewGRFOverride(s, t);
02125 break;
02126 }
02127
02128 case 0x12: {
02129 if (i == 0) {
02130 if (gvid != 0) {
02131 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
02132 return CIR_INVALID_ID;
02133 }
02134
02135 free(_cur_grffile->railtype_list);
02136 _cur_grffile->railtype_max = numinfo;
02137 _cur_grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
02138 }
02139
02140 RailTypeLabel rtl = buf->ReadDWord();
02141 _cur_grffile->railtype_list[i] = BSWAP32(rtl);
02142 break;
02143 }
02144
02145 case 0x13:
02146 case 0x14:
02147 while (buf->ReadByte() != 0) {
02148 buf->ReadString();
02149 }
02150 break;
02151
02152 default:
02153 ret = CIR_UNKNOWN;
02154 break;
02155 }
02156 }
02157
02158 return ret;
02159 }
02160
02161
02162 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
02163 {
02164 ChangeInfoResult ret = CIR_SUCCESS;
02165
02166 if (cid + numinfo > NUM_CARGO) {
02167 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
02168 return CIR_INVALID_ID;
02169 }
02170
02171 for (int i = 0; i < numinfo; i++) {
02172 CargoSpec *cs = CargoSpec::Get(cid + i);
02173
02174 switch (prop) {
02175 case 0x08:
02176 cs->bitnum = buf->ReadByte();
02177 if (cs->IsValid()) {
02178 cs->grffile = _cur_grffile;
02179 SetBit(_cargo_mask, cid + i);
02180 } else {
02181 ClrBit(_cargo_mask, cid + i);
02182 }
02183 break;
02184
02185 case 0x09:
02186 cs->name = buf->ReadWord();
02187 _string_to_grf_mapping[&cs->name] = _cur_grffile->grfid;
02188 break;
02189
02190 case 0x0A:
02191 cs->name_single = buf->ReadWord();
02192 _string_to_grf_mapping[&cs->name_single] = _cur_grffile->grfid;
02193 break;
02194
02195 case 0x0B:
02196 case 0x1B:
02197
02198
02199
02200 cs->units_volume = buf->ReadWord();
02201 _string_to_grf_mapping[&cs->units_volume] = _cur_grffile->grfid;
02202 break;
02203
02204 case 0x0C:
02205 case 0x1C:
02206
02207
02208
02209 cs->quantifier = buf->ReadWord();
02210 _string_to_grf_mapping[&cs->quantifier] = _cur_grffile->grfid;
02211 break;
02212
02213 case 0x0D:
02214 cs->abbrev = buf->ReadWord();
02215 _string_to_grf_mapping[&cs->abbrev] = _cur_grffile->grfid;
02216 break;
02217
02218 case 0x0E:
02219 cs->sprite = buf->ReadWord();
02220 break;
02221
02222 case 0x0F:
02223 cs->weight = buf->ReadByte();
02224 break;
02225
02226 case 0x10:
02227 cs->transit_days[0] = buf->ReadByte();
02228 break;
02229
02230 case 0x11:
02231 cs->transit_days[1] = buf->ReadByte();
02232 break;
02233
02234 case 0x12:
02235 cs->initial_payment = buf->ReadDWord();
02236 break;
02237
02238 case 0x13:
02239 cs->rating_colour = buf->ReadByte();
02240 break;
02241
02242 case 0x14:
02243 cs->legend_colour = buf->ReadByte();
02244 break;
02245
02246 case 0x15:
02247 cs->is_freight = (buf->ReadByte() != 0);
02248 break;
02249
02250 case 0x16:
02251 cs->classes = buf->ReadWord();
02252 break;
02253
02254 case 0x17:
02255 cs->label = buf->ReadDWord();
02256 cs->label = BSWAP32(cs->label);
02257 break;
02258
02259 case 0x18: {
02260 uint8 substitute_type = buf->ReadByte();
02261
02262 switch (substitute_type) {
02263 case 0x00: cs->town_effect = TE_PASSENGERS; break;
02264 case 0x02: cs->town_effect = TE_MAIL; break;
02265 case 0x05: cs->town_effect = TE_GOODS; break;
02266 case 0x09: cs->town_effect = TE_WATER; break;
02267 case 0x0B: cs->town_effect = TE_FOOD; break;
02268 default:
02269 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
02270 case 0xFF: cs->town_effect = TE_NONE; break;
02271 }
02272 break;
02273 }
02274
02275 case 0x19:
02276 cs->multipliertowngrowth = buf->ReadWord();
02277 break;
02278
02279 case 0x1A:
02280 cs->callback_mask = buf->ReadByte();
02281 break;
02282
02283 default:
02284 ret = CIR_UNKNOWN;
02285 break;
02286 }
02287 }
02288
02289 return ret;
02290 }
02291
02292
02293 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02294 {
02295 ChangeInfoResult ret = CIR_SUCCESS;
02296
02297 if (_cur_grffile->sound_offset == 0) {
02298 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02299 return CIR_INVALID_ID;
02300 }
02301
02302 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur_grffile->num_sounds) {
02303 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur_grffile->num_sounds);
02304 return CIR_INVALID_ID;
02305 }
02306
02307 for (int i = 0; i < numinfo; i++) {
02308 SoundEntry *sound = GetSound(sid + i + _cur_grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
02309
02310 switch (prop) {
02311 case 0x08:
02312 sound->volume = buf->ReadByte();
02313 break;
02314
02315 case 0x09:
02316 sound->priority = buf->ReadByte();
02317 break;
02318
02319 case 0x0A: {
02320 SoundID orig_sound = buf->ReadByte();
02321
02322 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02323 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02324 } else {
02325 SoundEntry *old_sound = GetSound(orig_sound);
02326
02327
02328 *old_sound = *sound;
02329 }
02330 break;
02331 }
02332
02333 default:
02334 ret = CIR_UNKNOWN;
02335 break;
02336 }
02337 }
02338
02339 return ret;
02340 }
02341
02342 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
02343 {
02344 ChangeInfoResult ret = CIR_SUCCESS;
02345
02346 switch (prop) {
02347 case 0x09:
02348 case 0x0D:
02349 case 0x0E:
02350 case 0x10:
02351 case 0x11:
02352 case 0x12:
02353 buf->ReadByte();
02354 break;
02355
02356 case 0x0A:
02357 case 0x0B:
02358 case 0x0C:
02359 case 0x0F:
02360 buf->ReadWord();
02361 break;
02362
02363 default:
02364 ret = CIR_UNKNOWN;
02365 break;
02366 }
02367 return ret;
02368 }
02369
02370 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02371 {
02372 ChangeInfoResult ret = CIR_SUCCESS;
02373
02374 if (indtid + numinfo > NUM_INDUSTRYTILES) {
02375 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02376 return CIR_INVALID_ID;
02377 }
02378
02379
02380 if (_cur_grffile->indtspec == NULL) {
02381 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02382 }
02383
02384 for (int i = 0; i < numinfo; i++) {
02385 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
02386
02387 if (prop != 0x08 && tsp == NULL) {
02388 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
02389 if (cir > ret) ret = cir;
02390 continue;
02391 }
02392
02393 switch (prop) {
02394 case 0x08: {
02395 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i];
02396 byte subs_id = buf->ReadByte();
02397
02398 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
02399
02400 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
02401 continue;
02402 }
02403
02404
02405 if (*tilespec == NULL) {
02406 *tilespec = CallocT<IndustryTileSpec>(1);
02407 tsp = *tilespec;
02408
02409 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
02410 tsp->enabled = true;
02411
02412
02413
02414
02415 tsp->anim_production = INDUSTRYTILE_NOANIM;
02416 tsp->anim_next = INDUSTRYTILE_NOANIM;
02417
02418 tsp->grf_prop.local_id = indtid + i;
02419 tsp->grf_prop.subst_id = subs_id;
02420 tsp->grf_prop.grffile = _cur_grffile;
02421 _industile_mngr.AddEntityID(indtid + i, _cur_grffile->grfid, subs_id);
02422 }
02423 break;
02424 }
02425
02426 case 0x09: {
02427 byte ovrid = buf->ReadByte();
02428
02429
02430 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
02431 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
02432 continue;
02433 }
02434
02435 _industile_mngr.Add(indtid + i, _cur_grffile->grfid, ovrid);
02436 break;
02437 }
02438
02439 case 0x0A:
02440 case 0x0B:
02441 case 0x0C: {
02442 uint16 acctp = buf->ReadWord();
02443 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
02444 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
02445 break;
02446 }
02447
02448 case 0x0D:
02449 tsp->slopes_refused = (Slope)buf->ReadByte();
02450 break;
02451
02452 case 0x0E:
02453 tsp->callback_mask = buf->ReadByte();
02454 break;
02455
02456 case 0x0F:
02457 tsp->animation.frames = buf->ReadByte();
02458 tsp->animation.status = buf->ReadByte();
02459 break;
02460
02461 case 0x10:
02462 tsp->animation.speed = buf->ReadByte();
02463 break;
02464
02465 case 0x11:
02466 tsp->animation.triggers = buf->ReadByte();
02467 break;
02468
02469 case 0x12:
02470 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
02471 break;
02472
02473 default:
02474 ret = CIR_UNKNOWN;
02475 break;
02476 }
02477 }
02478
02479 return ret;
02480 }
02481
02482 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
02483 {
02484 ChangeInfoResult ret = CIR_SUCCESS;
02485
02486 switch (prop) {
02487 case 0x09:
02488 case 0x0B:
02489 case 0x0F:
02490 case 0x12:
02491 case 0x13:
02492 case 0x14:
02493 case 0x17:
02494 case 0x18:
02495 case 0x19:
02496 case 0x21:
02497 case 0x22:
02498 buf->ReadByte();
02499 break;
02500
02501 case 0x0C:
02502 case 0x0D:
02503 case 0x0E:
02504 case 0x10:
02505 case 0x1B:
02506 case 0x1F:
02507 case 0x24:
02508 buf->ReadWord();
02509 break;
02510
02511 case 0x11:
02512 case 0x1A:
02513 case 0x1C:
02514 case 0x1D:
02515 case 0x1E:
02516 case 0x20:
02517 case 0x23:
02518 buf->ReadDWord();
02519 break;
02520
02521 case 0x0A: {
02522 byte num_table = buf->ReadByte();
02523 for (byte j = 0; j < num_table; j++) {
02524 for (uint k = 0;; k++) {
02525 byte x = buf->ReadByte();
02526 if (x == 0xFE && k == 0) {
02527 buf->ReadByte();
02528 buf->ReadByte();
02529 break;
02530 }
02531
02532 byte y = buf->ReadByte();
02533 if (x == 0 && y == 0x80) break;
02534
02535 byte gfx = buf->ReadByte();
02536 if (gfx == 0xFE) buf->ReadWord();
02537 }
02538 }
02539 break;
02540 }
02541
02542 case 0x16:
02543 for (byte j = 0; j < 3; j++) buf->ReadByte();
02544 break;
02545
02546 case 0x15: {
02547 byte number_of_sounds = buf->ReadByte();
02548 for (uint8 j = 0; j < number_of_sounds; j++) {
02549 buf->ReadByte();
02550 }
02551 break;
02552 }
02553
02554 default:
02555 ret = CIR_UNKNOWN;
02556 break;
02557 }
02558 return ret;
02559 }
02560
02567 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
02568 {
02569 for (int i = 0; i < size - 1; i++) {
02570 for (int j = i + 1; j < size; j++) {
02571 if (layout[i].ti.x == layout[j].ti.x &&
02572 layout[i].ti.y == layout[j].ti.y) {
02573 return false;
02574 }
02575 }
02576 }
02577 return true;
02578 }
02579
02581 static void CleanIndustryTileTable(IndustrySpec *ind)
02582 {
02583 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
02584 for (int j = 0; j < ind->num_table; j++) {
02585
02586 free((void*)ind->table[j]);
02587 }
02588
02589 free((void*)ind->table);
02590 ind->table = NULL;
02591 }
02592 }
02593
02594 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
02595 {
02596 ChangeInfoResult ret = CIR_SUCCESS;
02597
02598 if (indid + numinfo > NUM_INDUSTRYTYPES) {
02599 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
02600 return CIR_INVALID_ID;
02601 }
02602
02603 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
02604
02605
02606 if (_cur_grffile->industryspec == NULL) {
02607 _cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
02608 }
02609
02610 for (int i = 0; i < numinfo; i++) {
02611 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
02612
02613 if (prop != 0x08 && indsp == NULL) {
02614 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
02615 if (cir > ret) ret = cir;
02616 continue;
02617 }
02618
02619 switch (prop) {
02620 case 0x08: {
02621 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
02622 byte subs_id = buf->ReadByte();
02623
02624 if (subs_id == 0xFF) {
02625
02626
02627 _industry_specs[indid + i].enabled = false;
02628 continue;
02629 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
02630
02631 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
02632 continue;
02633 }
02634
02635
02636
02637
02638 if (*indspec == NULL) {
02639 *indspec = CallocT<IndustrySpec>(1);
02640 indsp = *indspec;
02641
02642 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
02643 indsp->enabled = true;
02644 indsp->grf_prop.local_id = indid + i;
02645 indsp->grf_prop.subst_id = subs_id;
02646 indsp->grf_prop.grffile = _cur_grffile;
02647
02648
02649 indsp->check_proc = CHECK_NOTHING;
02650 }
02651 break;
02652 }
02653
02654 case 0x09: {
02655 byte ovrid = buf->ReadByte();
02656
02657
02658 if (ovrid >= NEW_INDUSTRYOFFSET) {
02659 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
02660 continue;
02661 }
02662 indsp->grf_prop.override = ovrid;
02663 _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
02664 break;
02665 }
02666
02667 case 0x0A: {
02668 byte new_num_layouts = buf->ReadByte();
02669
02670
02671
02672
02673
02674 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
02675 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts);
02676 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles);
02677 uint size;
02678 const IndustryTileTable *copy_from;
02679
02680 try {
02681 for (byte j = 0; j < new_num_layouts; j++) {
02682 for (uint k = 0;; k++) {
02683 if (k >= def_num_tiles) {
02684 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
02685
02686 def_num_tiles *= 2;
02687 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
02688 }
02689
02690 itt[k].ti.x = buf->ReadByte();
02691
02692 if (itt[k].ti.x == 0xFE && k == 0) {
02693
02694 IndustryType type = buf->ReadByte();
02695 byte laynbr = buf->ReadByte();
02696
02697 copy_from = _origin_industry_specs[type].table[laynbr];
02698 for (size = 1;; size++) {
02699 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
02700 }
02701 break;
02702 }
02703
02704 itt[k].ti.y = buf->ReadByte();
02705
02706 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
02707
02708
02709 itt[k].ti.x = -0x80;
02710 itt[k].ti.y = 0;
02711 itt[k].gfx = 0;
02712
02713 size = k + 1;
02714 copy_from = itt;
02715 break;
02716 }
02717
02718 itt[k].gfx = buf->ReadByte();
02719
02720 if (itt[k].gfx == 0xFE) {
02721
02722 int local_tile_id = buf->ReadWord();
02723
02724
02725 int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
02726
02727 if (tempid == INVALID_INDUSTRYTILE) {
02728 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
02729 } else {
02730
02731 itt[k].gfx = tempid;
02732 size = k + 1;
02733 copy_from = itt;
02734 }
02735 } else if (itt[k].gfx == 0xFF) {
02736 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
02737 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
02738 }
02739 }
02740
02741 if (!ValidateIndustryLayout(copy_from, size)) {
02742
02743 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
02744 new_num_layouts--;
02745 j--;
02746 } else {
02747 tile_table[j] = CallocT<IndustryTileTable>(size);
02748 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
02749 }
02750 }
02751 } catch (...) {
02752 for (int i = 0; i < new_num_layouts; i++) {
02753 free(tile_table[i]);
02754 }
02755 free(tile_table);
02756 free(itt);
02757 throw;
02758 }
02759
02760
02761 CleanIndustryTileTable(indsp);
02762
02763 indsp->num_table = new_num_layouts;
02764 indsp->table = tile_table;
02765 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
02766 free(itt);
02767 break;
02768 }
02769
02770 case 0x0B:
02771 indsp->life_type = (IndustryLifeType)buf->ReadByte();
02772 break;
02773
02774 case 0x0C:
02775 indsp->closure_text = buf->ReadWord();
02776 _string_to_grf_mapping[&indsp->closure_text] = _cur_grffile->grfid;
02777 break;
02778
02779 case 0x0D:
02780 indsp->production_up_text = buf->ReadWord();
02781 _string_to_grf_mapping[&indsp->production_up_text] = _cur_grffile->grfid;
02782 break;
02783
02784 case 0x0E:
02785 indsp->production_down_text = buf->ReadWord();
02786 _string_to_grf_mapping[&indsp->production_down_text] = _cur_grffile->grfid;
02787 break;
02788
02789 case 0x0F:
02790 indsp->cost_multiplier = buf->ReadByte();
02791 break;
02792
02793 case 0x10:
02794 for (byte j = 0; j < 2; j++) {
02795 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02796 }
02797 break;
02798
02799 case 0x11:
02800 for (byte j = 0; j < 3; j++) {
02801 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02802 }
02803 buf->ReadByte();
02804 break;
02805
02806 case 0x12:
02807 case 0x13:
02808 indsp->production_rate[prop - 0x12] = buf->ReadByte();
02809 break;
02810
02811 case 0x14:
02812 indsp->minimal_cargo = buf->ReadByte();
02813 break;
02814
02815 case 0x15: {
02816 indsp->number_of_sounds = buf->ReadByte();
02817 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
02818
02819 try {
02820 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
02821 sounds[j] = buf->ReadByte();
02822 }
02823 } catch (...) {
02824 free(sounds);
02825 throw;
02826 }
02827
02828 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
02829 free((void*)indsp->random_sounds);
02830 }
02831 indsp->random_sounds = sounds;
02832 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
02833 break;
02834 }
02835
02836 case 0x16:
02837 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
02838 break;
02839
02840 case 0x17:
02841 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
02842 break;
02843
02844 case 0x18:
02845 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
02846 break;
02847
02848 case 0x19:
02849 indsp->map_colour = buf->ReadByte();
02850 break;
02851
02852 case 0x1A:
02853 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
02854 break;
02855
02856 case 0x1B:
02857 indsp->new_industry_text = buf->ReadWord();
02858 _string_to_grf_mapping[&indsp->new_industry_text] = _cur_grffile->grfid;
02859 break;
02860
02861 case 0x1C:
02862 case 0x1D:
02863 case 0x1E: {
02864 uint32 multiples = buf->ReadDWord();
02865 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
02866 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
02867 break;
02868 }
02869
02870 case 0x1F:
02871 indsp->name = buf->ReadWord();
02872 _string_to_grf_mapping[&indsp->name] = _cur_grffile->grfid;
02873 break;
02874
02875 case 0x20:
02876 indsp->prospecting_chance = buf->ReadDWord();
02877 break;
02878
02879 case 0x21:
02880 case 0x22: {
02881 byte aflag = buf->ReadByte();
02882 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
02883 break;
02884 }
02885
02886 case 0x23:
02887 indsp->removal_cost_multiplier = buf->ReadDWord();
02888 break;
02889
02890 case 0x24:
02891 indsp->station_name = buf->ReadWord();
02892 if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur_grffile->grfid;
02893 break;
02894
02895 default:
02896 ret = CIR_UNKNOWN;
02897 break;
02898 }
02899 }
02900
02901 return ret;
02902 }
02903
02909 static void DuplicateTileTable(AirportSpec *as)
02910 {
02911 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
02912 for (int i = 0; i < as->num_table; i++) {
02913 uint num_tiles = 1;
02914 const AirportTileTable *it = as->table[0];
02915 do {
02916 num_tiles++;
02917 } while ((++it)->ti.x != -0x80);
02918 table_list[i] = MallocT<AirportTileTable>(num_tiles);
02919 MemCpyT(table_list[i], as->table[i], num_tiles);
02920 }
02921 as->table = table_list;
02922 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
02923 MemCpyT(depot_table, as->depot_table, as->nof_depots);
02924 as->depot_table = depot_table;
02925 }
02926
02927 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
02928 {
02929 ChangeInfoResult ret = CIR_SUCCESS;
02930
02931 if (airport + numinfo > NUM_AIRPORTS) {
02932 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS);
02933 return CIR_INVALID_ID;
02934 }
02935
02936 grfmsg(1, "AirportChangeInfo: newid %u", airport);
02937
02938
02939 if (_cur_grffile->airportspec == NULL) {
02940 _cur_grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS);
02941 }
02942
02943 for (int i = 0; i < numinfo; i++) {
02944 AirportSpec *as = _cur_grffile->airportspec[airport + i];
02945
02946 if (as == NULL && prop != 0x08 && prop != 0x09) {
02947 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
02948 return CIR_INVALID_ID;
02949 }
02950
02951 switch (prop) {
02952 case 0x08: {
02953 byte subs_id = buf->ReadByte();
02954
02955 if (subs_id == 0xFF) {
02956
02957
02958 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
02959 continue;
02960 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
02961
02962 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
02963 continue;
02964 }
02965
02966 AirportSpec **spec = &_cur_grffile->airportspec[airport + i];
02967
02968
02969
02970 if (*spec == NULL) {
02971 *spec = MallocT<AirportSpec>(1);
02972 as = *spec;
02973
02974 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
02975 as->enabled = true;
02976 as->grf_prop.local_id = airport + i;
02977 as->grf_prop.subst_id = subs_id;
02978 as->grf_prop.grffile = _cur_grffile;
02979
02980 _airport_mngr.Add(airport + i, _cur_grffile->grfid, subs_id);
02981
02982 DuplicateTileTable(as);
02983 }
02984 break;
02985 }
02986
02987 case 0x0A: {
02988 as->num_table = buf->ReadByte();
02989 as->rotation = MallocT<Direction>(as->num_table);
02990 uint32 defsize = buf->ReadDWord();
02991 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table);
02992 AirportTileTable *att = CallocT<AirportTileTable>(defsize);
02993 int size;
02994 const AirportTileTable *copy_from;
02995 try {
02996 for (byte j = 0; j < as->num_table; j++) {
02997 as->rotation[j] = (Direction)buf->ReadByte();
02998 for (int k = 0;; k++) {
02999 att[k].ti.x = buf->ReadByte();
03000 att[k].ti.y = buf->ReadByte();
03001
03002 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
03003
03004
03005 att[k].ti.x = -0x80;
03006 att[k].ti.y = 0;
03007 att[k].gfx = 0;
03008
03009 size = k + 1;
03010 copy_from = att;
03011 break;
03012 }
03013
03014 att[k].gfx = buf->ReadByte();
03015
03016 if (att[k].gfx == 0xFE) {
03017
03018 int local_tile_id = buf->ReadWord();
03019
03020
03021 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
03022
03023 if (tempid == INVALID_AIRPORTTILE) {
03024 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
03025 } else {
03026
03027 att[k].gfx = tempid;
03028 size = k + 1;
03029 copy_from = att;
03030 }
03031 } else if (att[k].gfx == 0xFF) {
03032 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
03033 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
03034 }
03035
03036 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
03037 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
03038 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
03039 } else {
03040 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
03041 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
03042 }
03043 }
03044 tile_table[j] = CallocT<AirportTileTable>(size);
03045 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03046 }
03047
03048 as->table = tile_table;
03049 free(att);
03050 } catch (...) {
03051 for (int i = 0; i < as->num_table; i++) {
03052 free(tile_table[i]);
03053 }
03054 free(tile_table);
03055 free(att);
03056 throw;
03057 }
03058 break;
03059 }
03060
03061 case 0x0C:
03062 as->min_year = buf->ReadWord();
03063 as->max_year = buf->ReadWord();
03064 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
03065 break;
03066
03067 case 0x0D:
03068 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
03069 break;
03070
03071 case 0x0E:
03072 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
03073 break;
03074
03075 case 0x0F:
03076 as->noise_level = buf->ReadByte();
03077 break;
03078
03079 case 0x10:
03080 as->name = buf->ReadWord();
03081 _string_to_grf_mapping[&as->name] = _cur_grffile->grfid;
03082 break;
03083
03084 default:
03085 ret = CIR_UNKNOWN;
03086 break;
03087 }
03088 }
03089
03090 return ret;
03091 }
03092
03093 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
03094 {
03095 ChangeInfoResult ret = CIR_SUCCESS;
03096
03097 switch (prop) {
03098 case 0x0B:
03099 case 0x0C:
03100 case 0x0D:
03101 case 0x12:
03102 case 0x14:
03103 case 0x16:
03104 case 0x17:
03105 buf->ReadByte();
03106
03107 case 0x09:
03108 case 0x0A:
03109 case 0x10:
03110 case 0x11:
03111 case 0x13:
03112 case 0x15:
03113 buf->ReadWord();
03114 break;
03115
03116 case 0x08:
03117 case 0x0E:
03118 case 0x0F:
03119 buf->ReadDWord();
03120 break;
03121
03122 default:
03123 ret = CIR_UNKNOWN;
03124 break;
03125 }
03126
03127 return ret;
03128 }
03129
03130 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03131 {
03132 ChangeInfoResult ret = CIR_SUCCESS;
03133
03134 if (id + numinfo > NUM_OBJECTS) {
03135 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS);
03136 return CIR_INVALID_ID;
03137 }
03138
03139
03140 if (_cur_grffile->objectspec == NULL) {
03141 _cur_grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS);
03142 }
03143
03144 for (int i = 0; i < numinfo; i++) {
03145 ObjectSpec *spec = _cur_grffile->objectspec[id + i];
03146
03147 if (prop != 0x08 && spec == NULL) {
03148
03149 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
03150 if (cir > ret) ret = cir;
03151 continue;
03152 }
03153
03154 switch (prop) {
03155 case 0x08: {
03156 ObjectSpec **ospec = &_cur_grffile->objectspec[id + i];
03157
03158
03159 if (*ospec == NULL) {
03160 *ospec = CallocT<ObjectSpec>(1);
03161 (*ospec)->views = 1;
03162 }
03163
03164
03165 uint32 classid = buf->ReadDWord();
03166 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
03167 (*ospec)->enabled = true;
03168 break;
03169 }
03170
03171 case 0x09: {
03172 StringID class_name = buf->ReadWord();
03173 ObjectClass::SetName(spec->cls_id, class_name);
03174 _string_to_grf_mapping[&ObjectClass::classes[spec->cls_id].name] = _cur_grffile->grfid;
03175 break;
03176 }
03177
03178 case 0x0A:
03179 spec->name = buf->ReadWord();
03180 _string_to_grf_mapping[&spec->name] = _cur_grffile->grfid;
03181 break;
03182
03183 case 0x0B:
03184 spec->climate = buf->ReadByte();
03185 break;
03186
03187 case 0x0C:
03188 spec->size = buf->ReadByte();
03189 break;
03190
03191 case 0x0D:
03192 spec->build_cost_multiplier = buf->ReadByte();
03193 spec->clear_cost_multiplier = spec->build_cost_multiplier;
03194 break;
03195
03196 case 0x0E:
03197 spec->introduction_date = buf->ReadDWord();
03198 break;
03199
03200 case 0x0F:
03201 spec->end_of_life_date = buf->ReadDWord();
03202 break;
03203
03204 case 0x10:
03205 spec->flags = (ObjectFlags)buf->ReadWord();
03206 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
03207 break;
03208
03209 case 0x11:
03210 spec->animation.frames = buf->ReadByte();
03211 spec->animation.status = buf->ReadByte();
03212 break;
03213
03214 case 0x12:
03215 spec->animation.speed = buf->ReadByte();
03216 break;
03217
03218 case 0x13:
03219 spec->animation.triggers = buf->ReadWord();
03220 break;
03221
03222 case 0x14:
03223 spec->clear_cost_multiplier = buf->ReadByte();
03224 break;
03225
03226 case 0x15:
03227 spec->callback_mask = buf->ReadWord();
03228 break;
03229
03230 case 0x16:
03231 spec->height = buf->ReadByte();
03232 break;
03233
03234 case 0x17:
03235 spec->views = buf->ReadByte();
03236 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
03237 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
03238 spec->views = 1;
03239 }
03240 break;
03241
03242 default:
03243 ret = CIR_UNKNOWN;
03244 break;
03245 }
03246 }
03247
03248 return ret;
03249 }
03250
03251 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03252 {
03253 ChangeInfoResult ret = CIR_SUCCESS;
03254
03255 extern RailtypeInfo _railtypes[RAILTYPE_END];
03256
03257 if (id + numinfo > RAILTYPE_END) {
03258 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03259 return CIR_INVALID_ID;
03260 }
03261
03262 for (int i = 0; i < numinfo; i++) {
03263 RailType rt = _cur_grffile->railtype_map[id + i];
03264 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
03265
03266 RailtypeInfo *rti = &_railtypes[rt];
03267
03268 switch (prop) {
03269 case 0x08:
03270
03271 buf->ReadDWord();
03272 break;
03273
03274 case 0x09:
03275 rti->strings.toolbar_caption = buf->ReadWord();
03276 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur_grffile->grfid;
03277 break;
03278
03279 case 0x0A:
03280 rti->strings.menu_text = buf->ReadWord();
03281 _string_to_grf_mapping[&rti->strings.menu_text] = _cur_grffile->grfid;
03282 break;
03283
03284 case 0x0B:
03285 rti->strings.build_caption = buf->ReadWord();
03286 _string_to_grf_mapping[&rti->strings.build_caption] = _cur_grffile->grfid;
03287 break;
03288
03289 case 0x0C:
03290 rti->strings.replace_text = buf->ReadWord();
03291 _string_to_grf_mapping[&rti->strings.replace_text] = _cur_grffile->grfid;
03292 break;
03293
03294 case 0x0D:
03295 rti->strings.new_loco = buf->ReadWord();
03296 _string_to_grf_mapping[&rti->strings.new_loco] = _cur_grffile->grfid;
03297 break;
03298
03299 case 0x0E:
03300 case 0x0F:
03301 case 0x18:
03302 case 0x19:
03303 {
03304
03305
03306
03307 int n = buf->ReadByte();
03308 for (int j = 0; j != n; j++) {
03309 RailTypeLabel label = buf->ReadDWord();
03310 RailType rt = GetRailTypeByLabel(BSWAP32(label));
03311 if (rt != INVALID_RAILTYPE) {
03312 switch (prop) {
03313 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
03314 case 0x0F: SetBit(rti->powered_railtypes, rt); break;
03315 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
03316 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
03317 }
03318 }
03319 }
03320 break;
03321 }
03322
03323 case 0x10:
03324 rti->flags = (RailTypeFlags)buf->ReadByte();
03325 break;
03326
03327 case 0x11:
03328 rti->curve_speed = buf->ReadByte();
03329 break;
03330
03331 case 0x12:
03332 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
03333 break;
03334
03335 case 0x13:
03336 rti->cost_multiplier = buf->ReadWord();
03337 break;
03338
03339 case 0x14:
03340 rti->max_speed = buf->ReadWord();
03341 break;
03342
03343 case 0x15:
03344 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
03345 break;
03346
03347 case 0x16:
03348 rti->map_colour = buf->ReadByte();
03349 break;
03350
03351 case 0x17:
03352 rti->introduction_date = buf->ReadDWord();
03353 break;
03354
03355 case 0x1A:
03356 rti->sorting_order = buf->ReadByte();
03357 break;
03358
03359 default:
03360 ret = CIR_UNKNOWN;
03361 break;
03362 }
03363 }
03364
03365 return ret;
03366 }
03367
03368 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
03369 {
03370 ChangeInfoResult ret = CIR_SUCCESS;
03371
03372 if (id + numinfo > RAILTYPE_END) {
03373 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03374 return CIR_INVALID_ID;
03375 }
03376
03377 for (int i = 0; i < numinfo; i++) {
03378 switch (prop) {
03379 case 0x08:
03380 {
03381 RailTypeLabel rtl = buf->ReadDWord();
03382 rtl = BSWAP32(rtl);
03383
03384 RailType rt = GetRailTypeByLabel(rtl);
03385 if (rt == INVALID_RAILTYPE) {
03386
03387 rt = AllocateRailType(rtl);
03388 }
03389
03390 _cur_grffile->railtype_map[id + i] = rt;
03391 break;
03392 }
03393
03394 case 0x09:
03395 case 0x0A:
03396 case 0x0B:
03397 case 0x0C:
03398 case 0x0D:
03399 case 0x13:
03400 case 0x14:
03401 buf->ReadWord();
03402 break;
03403
03404 case 0x0E:
03405 case 0x0F:
03406 case 0x18:
03407 case 0x19:
03408 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
03409 break;
03410
03411 case 0x10:
03412 case 0x11:
03413 case 0x12:
03414 case 0x15:
03415 case 0x16:
03416 case 0x1A:
03417 buf->ReadByte();
03418 break;
03419
03420 case 0x17:
03421 buf->ReadDWord();
03422 break;
03423
03424 default:
03425 ret = CIR_UNKNOWN;
03426 break;
03427 }
03428 }
03429
03430 return ret;
03431 }
03432
03433 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
03434 {
03435 ChangeInfoResult ret = CIR_SUCCESS;
03436
03437 if (airtid + numinfo > NUM_AIRPORTTILES) {
03438 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
03439 return CIR_INVALID_ID;
03440 }
03441
03442
03443 if (_cur_grffile->airtspec == NULL) {
03444 _cur_grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
03445 }
03446
03447 for (int i = 0; i < numinfo; i++) {
03448 AirportTileSpec *tsp = _cur_grffile->airtspec[airtid + i];
03449
03450 if (prop != 0x08 && tsp == NULL) {
03451 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
03452 return CIR_INVALID_ID;
03453 }
03454
03455 switch (prop) {
03456 case 0x08: {
03457 AirportTileSpec **tilespec = &_cur_grffile->airtspec[airtid + i];
03458 byte subs_id = buf->ReadByte();
03459
03460 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
03461
03462 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
03463 continue;
03464 }
03465
03466
03467 if (*tilespec == NULL) {
03468 *tilespec = CallocT<AirportTileSpec>(1);
03469 tsp = *tilespec;
03470
03471 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
03472 tsp->enabled = true;
03473
03474 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
03475
03476 tsp->grf_prop.local_id = airtid + i;
03477 tsp->grf_prop.subst_id = subs_id;
03478 tsp->grf_prop.grffile = _cur_grffile;
03479 _airporttile_mngr.AddEntityID(airtid + i, _cur_grffile->grfid, subs_id);
03480 }
03481 break;
03482 }
03483
03484 case 0x09: {
03485 byte override = buf->ReadByte();
03486
03487
03488 if (override >= NEW_AIRPORTTILE_OFFSET) {
03489 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
03490 continue;
03491 }
03492
03493 _airporttile_mngr.Add(airtid + i, _cur_grffile->grfid, override);
03494 break;
03495 }
03496
03497 case 0x0E:
03498 tsp->callback_mask = buf->ReadByte();
03499 break;
03500
03501 case 0x0F:
03502 tsp->animation.frames = buf->ReadByte();
03503 tsp->animation.status = buf->ReadByte();
03504 break;
03505
03506 case 0x10:
03507 tsp->animation.speed = buf->ReadByte();
03508 break;
03509
03510 case 0x11:
03511 tsp->animation.triggers = buf->ReadByte();
03512 break;
03513
03514 default:
03515 ret = CIR_UNKNOWN;
03516 break;
03517 }
03518 }
03519
03520 return ret;
03521 }
03522
03523 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
03524 {
03525 switch (cir) {
03526 default: NOT_REACHED();
03527
03528 case CIR_SUCCESS:
03529 return false;
03530
03531 case CIR_UNHANDLED:
03532 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
03533 return false;
03534
03535 case CIR_UNKNOWN:
03536 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
03537
03538
03539 case CIR_INVALID_ID:
03540
03541 DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
03542 return true;
03543 }
03544 }
03545
03546
03547 static void FeatureChangeInfo(ByteReader *buf)
03548 {
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560 static const VCI_Handler handler[] = {
03561 RailVehicleChangeInfo,
03562 RoadVehicleChangeInfo,
03563 ShipVehicleChangeInfo,
03564 AircraftVehicleChangeInfo,
03565 StationChangeInfo,
03566 CanalChangeInfo,
03567 BridgeChangeInfo,
03568 TownHouseChangeInfo,
03569 GlobalVarChangeInfo,
03570 IndustrytilesChangeInfo,
03571 IndustriesChangeInfo,
03572 NULL,
03573 SoundEffectChangeInfo,
03574 AirportChangeInfo,
03575 NULL,
03576 ObjectChangeInfo,
03577 RailTypeChangeInfo,
03578 AirportTilesChangeInfo,
03579 };
03580
03581 uint8 feature = buf->ReadByte();
03582 uint8 numprops = buf->ReadByte();
03583 uint numinfo = buf->ReadByte();
03584 uint engine = buf->ReadExtendedByte();
03585
03586 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
03587 feature, numprops, engine, numinfo);
03588
03589 if (feature >= lengthof(handler) || handler[feature] == NULL) {
03590 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
03591 return;
03592 }
03593
03594
03595 SetBit(_cur_grffile->grf_features, feature);
03596
03597 while (numprops-- && buf->HasData()) {
03598 uint8 prop = buf->ReadByte();
03599
03600 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
03601 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
03602 }
03603 }
03604
03605
03606 static void SafeChangeInfo(ByteReader *buf)
03607 {
03608 uint8 feature = buf->ReadByte();
03609 uint8 numprops = buf->ReadByte();
03610 uint numinfo = buf->ReadByte();
03611 buf->ReadExtendedByte();
03612
03613 if (feature == GSF_BRIDGES && numprops == 1) {
03614 uint8 prop = buf->ReadByte();
03615
03616
03617 if (prop == 0x0D) return;
03618 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
03619 uint8 prop = buf->ReadByte();
03620
03621 if (prop == 0x11) {
03622 bool is_safe = true;
03623 for (uint i = 0; i < numinfo; i++) {
03624 uint32 s = buf->ReadDWord();
03625 buf->ReadDWord();
03626 const GRFConfig *grfconfig = GetGRFConfig(s);
03627 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
03628 is_safe = false;
03629 break;
03630 }
03631 }
03632 if (is_safe) return;
03633 }
03634 }
03635
03636 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
03637
03638
03639 _skip_sprites = -1;
03640 }
03641
03642
03643 static void ReserveChangeInfo(ByteReader *buf)
03644 {
03645 uint8 feature = buf->ReadByte();
03646
03647 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
03648
03649 uint8 numprops = buf->ReadByte();
03650 uint8 numinfo = buf->ReadByte();
03651 uint8 index = buf->ReadExtendedByte();
03652
03653 while (numprops-- && buf->HasData()) {
03654 uint8 prop = buf->ReadByte();
03655 ChangeInfoResult cir = CIR_SUCCESS;
03656
03657 switch (feature) {
03658 default: NOT_REACHED();
03659 case GSF_CARGOS:
03660 cir = CargoChangeInfo(index, numinfo, prop, buf);
03661 break;
03662
03663 case GSF_GLOBALVAR:
03664 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
03665 break;
03666
03667 case GSF_RAILTYPES:
03668 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
03669 break;
03670 }
03671
03672 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
03673 }
03674 }
03675
03676
03677 static void NewSpriteSet(ByteReader *buf)
03678 {
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691 uint8 feature = buf->ReadByte();
03692 uint8 num_sets = buf->ReadByte();
03693 uint16 num_ents = buf->ReadExtendedByte();
03694
03695 _cur_grffile->spriteset_start = _cur_spriteid;
03696 _cur_grffile->spriteset_feature = feature;
03697 _cur_grffile->spriteset_numsets = num_sets;
03698 _cur_grffile->spriteset_numents = num_ents;
03699
03700 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
03701 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
03702 );
03703
03704 for (int i = 0; i < num_sets * num_ents; i++) {
03705 _nfo_line++;
03706 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
03707 }
03708 }
03709
03710
03711 static void SkipAct1(ByteReader *buf)
03712 {
03713 buf->ReadByte();
03714 uint8 num_sets = buf->ReadByte();
03715 uint16 num_ents = buf->ReadExtendedByte();
03716
03717 _skip_sprites = num_sets * num_ents;
03718
03719 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
03720 }
03721
03722
03723
03724 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
03725 {
03726 if (HasBit(groupid, 15)) {
03727 assert(CallbackResultSpriteGroup::CanAllocateItem());
03728 return new CallbackResultSpriteGroup(groupid);
03729 }
03730
03731 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03732 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
03733 return NULL;
03734 }
03735
03736 return _cur_grffile->spritegroups[groupid];
03737 }
03738
03739
03740 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
03741 {
03742 if (HasBit(spriteid, 15)) {
03743 assert(CallbackResultSpriteGroup::CanAllocateItem());
03744 return new CallbackResultSpriteGroup(spriteid);
03745 }
03746
03747 if (spriteid >= _cur_grffile->spriteset_numsets) {
03748 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
03749 return NULL;
03750 }
03751
03752
03753
03754
03755 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
03756 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
03757 setid, type,
03758 _cur_grffile->spriteset_start + spriteid * num_sprites,
03759 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
03760 return NULL;
03761 }
03762
03763 if (feature != _cur_grffile->spriteset_feature) {
03764 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
03765 setid, type,
03766 _cur_grffile->spriteset_feature, feature);
03767 return NULL;
03768 }
03769
03770 assert(ResultSpriteGroup::CanAllocateItem());
03771 return new ResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
03772 }
03773
03774
03775 static void NewSpriteGroup(ByteReader *buf)
03776 {
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787 SpriteGroup *act_group = NULL;
03788
03789 uint8 feature = buf->ReadByte();
03790 uint8 setid = buf->ReadByte();
03791 uint8 type = buf->ReadByte();
03792
03793 if (setid >= _cur_grffile->spritegroups_count) {
03794
03795 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
03796
03797 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++) {
03798 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
03799 }
03800 }
03801
03802
03803
03804
03805
03806 switch (type) {
03807
03808 case 0x81:
03809 case 0x82:
03810 case 0x85:
03811 case 0x86:
03812 case 0x89:
03813 case 0x8A:
03814 {
03815 byte varadjust;
03816 byte varsize;
03817
03818 assert(DeterministicSpriteGroup::CanAllocateItem());
03819 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
03820 act_group = group;
03821 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03822
03823 switch (GB(type, 2, 2)) {
03824 default: NOT_REACHED();
03825 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
03826 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
03827 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
03828 }
03829
03830
03831
03832 do {
03833 DeterministicSpriteGroupAdjust *adjust;
03834
03835 group->num_adjusts++;
03836 group->adjusts = ReallocT(group->adjusts, group->num_adjusts);
03837
03838 adjust = &group->adjusts[group->num_adjusts - 1];
03839
03840
03841 adjust->operation = group->num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
03842 adjust->variable = buf->ReadByte();
03843 if (adjust->variable == 0x7E) {
03844
03845 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
03846 } else {
03847 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
03848 }
03849
03850 varadjust = buf->ReadByte();
03851 adjust->shift_num = GB(varadjust, 0, 5);
03852 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
03853 adjust->and_mask = buf->ReadVarSize(varsize);
03854
03855 if (adjust->type != DSGA_TYPE_NONE) {
03856 adjust->add_val = buf->ReadVarSize(varsize);
03857 adjust->divmod_val = buf->ReadVarSize(varsize);
03858 } else {
03859 adjust->add_val = 0;
03860 adjust->divmod_val = 0;
03861 }
03862
03863
03864 } while (HasBit(varadjust, 5));
03865
03866 group->num_ranges = buf->ReadByte();
03867 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
03868
03869 for (uint i = 0; i < group->num_ranges; i++) {
03870 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
03871 group->ranges[i].low = buf->ReadVarSize(varsize);
03872 group->ranges[i].high = buf->ReadVarSize(varsize);
03873 }
03874
03875 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
03876 break;
03877 }
03878
03879
03880 case 0x80:
03881 case 0x83:
03882 case 0x84:
03883 {
03884 assert(RandomizedSpriteGroup::CanAllocateItem());
03885 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
03886 act_group = group;
03887 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03888
03889 if (HasBit(type, 2)) {
03890 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
03891 group->count = buf->ReadByte();
03892 }
03893
03894 uint8 triggers = buf->ReadByte();
03895 group->triggers = GB(triggers, 0, 7);
03896 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
03897 group->lowest_randbit = buf->ReadByte();
03898 group->num_groups = buf->ReadByte();
03899 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
03900
03901 for (uint i = 0; i < group->num_groups; i++) {
03902 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
03903 }
03904
03905 break;
03906 }
03907
03908
03909 default:
03910 {
03911 switch (feature) {
03912 case GSF_TRAINS:
03913 case GSF_ROADVEHICLES:
03914 case GSF_SHIPS:
03915 case GSF_AIRCRAFT:
03916 case GSF_STATIONS:
03917 case GSF_CANALS:
03918 case GSF_CARGOS:
03919 case GSF_AIRPORTS:
03920 case GSF_RAILTYPES:
03921 {
03922 byte sprites = _cur_grffile->spriteset_numents;
03923 byte num_loaded = type;
03924 byte num_loading = buf->ReadByte();
03925
03926 if (_cur_grffile->spriteset_start == 0) {
03927 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
03928 return;
03929 }
03930
03931 assert(RealSpriteGroup::CanAllocateItem());
03932 RealSpriteGroup *group = new RealSpriteGroup();
03933 act_group = group;
03934
03935 group->num_loaded = num_loaded;
03936 group->num_loading = num_loading;
03937 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
03938 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
03939
03940 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
03941 setid, sprites, num_loaded, num_loading);
03942
03943 for (uint i = 0; i < num_loaded; i++) {
03944 uint16 spriteid = buf->ReadWord();
03945 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03946 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
03947 }
03948
03949 for (uint i = 0; i < num_loading; i++) {
03950 uint16 spriteid = buf->ReadWord();
03951 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03952 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
03953 }
03954
03955 break;
03956 }
03957
03958 case GSF_HOUSES:
03959 case GSF_AIRPORTTILES:
03960 case GSF_OBJECTS:
03961 case GSF_INDUSTRYTILES: {
03962 byte num_spriteset_ents = _cur_grffile->spriteset_numents;
03963 byte num_spritesets = _cur_grffile->spriteset_numsets;
03964 byte num_building_sprites = max((uint8)1, type);
03965 uint i;
03966
03967 assert(TileLayoutSpriteGroup::CanAllocateItem());
03968 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
03969 act_group = group;
03970
03971 group->num_building_stages = max((uint8)1, num_spriteset_ents);
03972
03973
03974 ReadSpriteLayoutSprite(buf, false, _cur_grffile->spriteset_start, num_spriteset_ents, num_spritesets, &group->dts.ground);
03975
03976 group->dts.Allocate(num_building_sprites);
03977 for (i = 0; i < num_building_sprites; i++) {
03978 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts.seq[i]);
03979
03980 ReadSpriteLayoutSprite(buf, false, _cur_grffile->spriteset_start, num_spriteset_ents, num_spritesets, &seq->image);
03981 seq->delta_x = buf->ReadByte();
03982 seq->delta_y = buf->ReadByte();
03983
03984 if (type > 0) {
03985 seq->delta_z = buf->ReadByte();
03986 if (!seq->IsParentSprite()) continue;
03987 }
03988
03989 seq->size_x = buf->ReadByte();
03990 seq->size_y = buf->ReadByte();
03991 seq->size_z = buf->ReadByte();
03992 }
03993 break;
03994 }
03995
03996 case GSF_INDUSTRIES: {
03997 if (type > 1) {
03998 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
03999 break;
04000 }
04001
04002 assert(IndustryProductionSpriteGroup::CanAllocateItem());
04003 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04004 act_group = group;
04005 group->version = type;
04006 if (type == 0) {
04007 for (uint i = 0; i < 3; i++) {
04008 group->subtract_input[i] = (int16)buf->ReadWord();
04009 }
04010 for (uint i = 0; i < 2; i++) {
04011 group->add_output[i] = buf->ReadWord();
04012 }
04013 group->again = buf->ReadByte();
04014 } else {
04015 for (uint i = 0; i < 3; i++) {
04016 group->subtract_input[i] = buf->ReadByte();
04017 }
04018 for (uint i = 0; i < 2; i++) {
04019 group->add_output[i] = buf->ReadByte();
04020 }
04021 group->again = buf->ReadByte();
04022 }
04023 break;
04024 }
04025
04026
04027 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04028 }
04029 }
04030 }
04031
04032 _cur_grffile->spritegroups[setid] = act_group;
04033 }
04034
04035 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04036 {
04037 if (feature == GSF_OBJECTS) {
04038 switch (ctype) {
04039 case 0: return 0;
04040 case 0xFF: return CT_PURCHASE_OBJECT;
04041 default:
04042 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04043 return CT_INVALID;
04044 }
04045 }
04046
04047 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04048 if (ctype == 0xFF) return CT_PURCHASE;
04049
04050 if (_cur_grffile->cargo_max == 0) {
04051
04052 if (ctype >= 32) {
04053 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04054 return CT_INVALID;
04055 }
04056
04057 const CargoSpec *cs;
04058 FOR_ALL_CARGOSPECS(cs) {
04059 if (cs->bitnum == ctype) {
04060 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04061 return cs->Index();
04062 }
04063 }
04064
04065 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04066 return CT_INVALID;
04067 }
04068
04069
04070 if (ctype >= _cur_grffile->cargo_max) {
04071 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
04072 return CT_INVALID;
04073 }
04074
04075
04076 CargoLabel cl = _cur_grffile->cargo_list[ctype];
04077 if (cl == 0) {
04078 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04079 return CT_INVALID;
04080 }
04081
04082 ctype = GetCargoIDByLabel(cl);
04083 if (ctype == CT_INVALID) {
04084 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));
04085 return CT_INVALID;
04086 }
04087
04088 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);
04089 return ctype;
04090 }
04091
04092
04093 static bool IsValidGroupID(uint16 groupid, const char *function)
04094 {
04095 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
04096 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
04097 return false;
04098 }
04099
04100 return true;
04101 }
04102
04103 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04104 {
04105 static EngineID *last_engines;
04106 static uint last_engines_count;
04107 bool wagover = false;
04108
04109
04110 if (HasBit(idcount, 7)) {
04111 wagover = true;
04112
04113 idcount = GB(idcount, 0, 7);
04114
04115 if (last_engines_count == 0) {
04116 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04117 return;
04118 }
04119
04120 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04121 last_engines_count, idcount);
04122 } else {
04123 if (last_engines_count != idcount) {
04124 last_engines = ReallocT(last_engines, idcount);
04125 last_engines_count = idcount;
04126 }
04127 }
04128
04129 EngineID *engines = AllocaM(EngineID, idcount);
04130 for (uint i = 0; i < idcount; i++) {
04131 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, buf->ReadExtendedByte());
04132 if (e == NULL) {
04133
04134
04135
04136 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04137 return;
04138 }
04139
04140 engines[i] = e->index;
04141 if (!wagover) last_engines[i] = engines[i];
04142 }
04143
04144 uint8 cidcount = buf->ReadByte();
04145 for (uint c = 0; c < cidcount; c++) {
04146 uint8 ctype = buf->ReadByte();
04147 uint16 groupid = buf->ReadWord();
04148 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04149
04150 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04151
04152 ctype = TranslateCargo(feature, ctype);
04153 if (ctype == CT_INVALID) continue;
04154
04155 for (uint i = 0; i < idcount; i++) {
04156 EngineID engine = engines[i];
04157
04158 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04159
04160 if (wagover) {
04161 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
04162 } else {
04163 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
04164 }
04165 }
04166 }
04167
04168 uint16 groupid = buf->ReadWord();
04169 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04170
04171 grfmsg(8, "-- Default group id 0x%04X", groupid);
04172
04173 for (uint i = 0; i < idcount; i++) {
04174 EngineID engine = engines[i];
04175
04176 if (wagover) {
04177 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
04178 } else {
04179 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
04180 SetEngineGRF(engine, _cur_grffile);
04181 }
04182 }
04183 }
04184
04185
04186 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04187 {
04188 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04189 for (uint i = 0; i < idcount; i++) {
04190 cfs[i] = (CanalFeature)buf->ReadByte();
04191 }
04192
04193 uint8 cidcount = buf->ReadByte();
04194 buf->Skip(cidcount * 3);
04195
04196 uint16 groupid = buf->ReadWord();
04197 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04198
04199 for (uint i = 0; i < idcount; i++) {
04200 CanalFeature cf = cfs[i];
04201
04202 if (cf >= CF_END) {
04203 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04204 continue;
04205 }
04206
04207 _water_feature[cf].grffile = _cur_grffile;
04208 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
04209 }
04210 }
04211
04212
04213 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04214 {
04215 uint8 *stations = AllocaM(uint8, idcount);
04216 for (uint i = 0; i < idcount; i++) {
04217 stations[i] = buf->ReadByte();
04218 }
04219
04220 uint8 cidcount = buf->ReadByte();
04221 for (uint c = 0; c < cidcount; c++) {
04222 uint8 ctype = buf->ReadByte();
04223 uint16 groupid = buf->ReadWord();
04224 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04225
04226 ctype = TranslateCargo(GSF_STATIONS, ctype);
04227 if (ctype == CT_INVALID) continue;
04228
04229 for (uint i = 0; i < idcount; i++) {
04230 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
04231
04232 if (statspec == NULL) {
04233 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04234 continue;
04235 }
04236
04237 statspec->grf_prop.spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
04238 }
04239 }
04240
04241 uint16 groupid = buf->ReadWord();
04242 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04243
04244 for (uint i = 0; i < idcount; i++) {
04245 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
04246
04247 if (statspec == NULL) {
04248 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04249 continue;
04250 }
04251
04252 if (statspec->grf_prop.grffile != NULL) {
04253 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04254 continue;
04255 }
04256
04257 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
04258 statspec->grf_prop.grffile = _cur_grffile;
04259 statspec->grf_prop.local_id = stations[i];
04260 StationClass::Assign(statspec);
04261 }
04262 }
04263
04264
04265 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04266 {
04267 uint8 *houses = AllocaM(uint8, idcount);
04268 for (uint i = 0; i < idcount; i++) {
04269 houses[i] = buf->ReadByte();
04270 }
04271
04272
04273 uint8 cidcount = buf->ReadByte();
04274 buf->Skip(cidcount * 3);
04275
04276 uint16 groupid = buf->ReadWord();
04277 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04278
04279 if (_cur_grffile->housespec == NULL) {
04280 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04281 return;
04282 }
04283
04284 for (uint i = 0; i < idcount; i++) {
04285 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
04286
04287 if (hs == NULL) {
04288 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04289 continue;
04290 }
04291
04292 hs->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04293 }
04294 }
04295
04296 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04297 {
04298 uint8 *industries = AllocaM(uint8, idcount);
04299 for (uint i = 0; i < idcount; i++) {
04300 industries[i] = buf->ReadByte();
04301 }
04302
04303
04304 uint8 cidcount = buf->ReadByte();
04305 buf->Skip(cidcount * 3);
04306
04307 uint16 groupid = buf->ReadWord();
04308 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04309
04310 if (_cur_grffile->industryspec == NULL) {
04311 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04312 return;
04313 }
04314
04315 for (uint i = 0; i < idcount; i++) {
04316 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
04317
04318 if (indsp == NULL) {
04319 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04320 continue;
04321 }
04322
04323 indsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04324 }
04325 }
04326
04327 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04328 {
04329 uint8 *indtiles = AllocaM(uint8, idcount);
04330 for (uint i = 0; i < idcount; i++) {
04331 indtiles[i] = buf->ReadByte();
04332 }
04333
04334
04335 uint8 cidcount = buf->ReadByte();
04336 buf->Skip(cidcount * 3);
04337
04338 uint16 groupid = buf->ReadWord();
04339 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
04340
04341 if (_cur_grffile->indtspec == NULL) {
04342 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
04343 return;
04344 }
04345
04346 for (uint i = 0; i < idcount; i++) {
04347 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
04348
04349 if (indtsp == NULL) {
04350 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
04351 continue;
04352 }
04353
04354 indtsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04355 }
04356 }
04357
04358 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
04359 {
04360 CargoID *cargos = AllocaM(CargoID, idcount);
04361 for (uint i = 0; i < idcount; i++) {
04362 cargos[i] = buf->ReadByte();
04363 }
04364
04365
04366 uint8 cidcount = buf->ReadByte();
04367 buf->Skip(cidcount * 3);
04368
04369 uint16 groupid = buf->ReadWord();
04370 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
04371
04372 for (uint i = 0; i < idcount; i++) {
04373 CargoID cid = cargos[i];
04374
04375 if (cid >= NUM_CARGO) {
04376 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
04377 continue;
04378 }
04379
04380 CargoSpec *cs = CargoSpec::Get(cid);
04381 cs->grffile = _cur_grffile;
04382 cs->group = _cur_grffile->spritegroups[groupid];
04383 }
04384 }
04385
04386 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
04387 {
04388 if (_cur_grffile->objectspec == NULL) {
04389 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
04390 return;
04391 }
04392
04393 uint8 *objects = AllocaM(uint8, idcount);
04394 for (uint i = 0; i < idcount; i++) {
04395 objects[i] = buf->ReadByte();
04396 }
04397
04398 uint8 cidcount = buf->ReadByte();
04399 for (uint c = 0; c < cidcount; c++) {
04400 uint8 ctype = buf->ReadByte();
04401 uint16 groupid = buf->ReadWord();
04402 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
04403
04404 ctype = TranslateCargo(GSF_OBJECTS, ctype);
04405 if (ctype == CT_INVALID) continue;
04406
04407 for (uint i = 0; i < idcount; i++) {
04408 ObjectSpec *spec = _cur_grffile->objectspec[objects[i]];
04409
04410 if (spec == NULL) {
04411 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04412 continue;
04413 }
04414
04415 spec->grf_prop.spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
04416 }
04417 }
04418
04419 uint16 groupid = buf->ReadWord();
04420 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
04421
04422 for (uint i = 0; i < idcount; i++) {
04423 ObjectSpec *spec = _cur_grffile->objectspec[objects[i]];
04424
04425 if (spec == NULL) {
04426 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04427 continue;
04428 }
04429
04430 if (spec->grf_prop.grffile != NULL) {
04431 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
04432 continue;
04433 }
04434
04435 spec->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04436 spec->grf_prop.grffile = _cur_grffile;
04437 spec->grf_prop.local_id = objects[i];
04438 }
04439 }
04440
04441 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
04442 {
04443 uint8 *railtypes = AllocaM(uint8, idcount);
04444 for (uint i = 0; i < idcount; i++) {
04445 railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
04446 }
04447
04448 uint8 cidcount = buf->ReadByte();
04449 for (uint c = 0; c < cidcount; c++) {
04450 uint8 ctype = buf->ReadByte();
04451 uint16 groupid = buf->ReadWord();
04452 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
04453
04454 if (ctype >= RTSG_END) continue;
04455
04456 extern RailtypeInfo _railtypes[RAILTYPE_END];
04457 for (uint i = 0; i < idcount; i++) {
04458 if (railtypes[i] != INVALID_RAILTYPE) {
04459 RailtypeInfo *rti = &_railtypes[railtypes[i]];
04460
04461 rti->group[ctype] = _cur_grffile->spritegroups[groupid];
04462 }
04463 }
04464 }
04465
04466
04467 buf->ReadWord();
04468 }
04469
04470 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
04471 {
04472 uint8 *airports = AllocaM(uint8, idcount);
04473 for (uint i = 0; i < idcount; i++) {
04474 airports[i] = buf->ReadByte();
04475 }
04476
04477
04478 uint8 cidcount = buf->ReadByte();
04479 buf->Skip(cidcount * 3);
04480
04481 uint16 groupid = buf->ReadWord();
04482 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
04483
04484 if (_cur_grffile->airportspec == NULL) {
04485 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
04486 return;
04487 }
04488
04489 for (uint i = 0; i < idcount; i++) {
04490 AirportSpec *as = _cur_grffile->airportspec[airports[i]];
04491
04492 if (as == NULL) {
04493 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
04494 continue;
04495 }
04496
04497 as->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04498 }
04499 }
04500
04501 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04502 {
04503 uint8 *airptiles = AllocaM(uint8, idcount);
04504 for (uint i = 0; i < idcount; i++) {
04505 airptiles[i] = buf->ReadByte();
04506 }
04507
04508
04509 uint8 cidcount = buf->ReadByte();
04510 buf->Skip(cidcount * 3);
04511
04512 uint16 groupid = buf->ReadWord();
04513 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
04514
04515 if (_cur_grffile->airtspec == NULL) {
04516 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
04517 return;
04518 }
04519
04520 for (uint i = 0; i < idcount; i++) {
04521 AirportTileSpec *airtsp = _cur_grffile->airtspec[airptiles[i]];
04522
04523 if (airtsp == NULL) {
04524 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
04525 continue;
04526 }
04527
04528 airtsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04529 }
04530 }
04531
04532
04533
04534 static void FeatureMapSpriteGroup(ByteReader *buf)
04535 {
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550 if (_cur_grffile->spritegroups == NULL) {
04551 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
04552 return;
04553 }
04554
04555 uint8 feature = buf->ReadByte();
04556 uint8 idcount = buf->ReadByte();
04557
04558
04559 if (idcount == 0) {
04560
04561 buf->ReadByte();
04562 uint16 groupid = buf->ReadWord();
04563 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
04564
04565 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
04566
04567 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
04568 return;
04569 }
04570
04571
04572 SetBit(_cur_grffile->grf_features, feature);
04573
04574 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
04575
04576 switch (feature) {
04577 case GSF_TRAINS:
04578 case GSF_ROADVEHICLES:
04579 case GSF_SHIPS:
04580 case GSF_AIRCRAFT:
04581 VehicleMapSpriteGroup(buf, feature, idcount);
04582 return;
04583
04584 case GSF_CANALS:
04585 CanalMapSpriteGroup(buf, idcount);
04586 return;
04587
04588 case GSF_STATIONS:
04589 StationMapSpriteGroup(buf, idcount);
04590 return;
04591
04592 case GSF_HOUSES:
04593 TownHouseMapSpriteGroup(buf, idcount);
04594 return;
04595
04596 case GSF_INDUSTRIES:
04597 IndustryMapSpriteGroup(buf, idcount);
04598 return;
04599
04600 case GSF_INDUSTRYTILES:
04601 IndustrytileMapSpriteGroup(buf, idcount);
04602 return;
04603
04604 case GSF_CARGOS:
04605 CargoMapSpriteGroup(buf, idcount);
04606 return;
04607
04608 case GSF_AIRPORTS:
04609 AirportMapSpriteGroup(buf, idcount);
04610 return;
04611
04612 case GSF_OBJECTS:
04613 ObjectMapSpriteGroup(buf, idcount);
04614 break;
04615
04616 case GSF_RAILTYPES:
04617 RailTypeMapSpriteGroup(buf, idcount);
04618 break;
04619
04620 case GSF_AIRPORTTILES:
04621 AirportTileMapSpriteGroup(buf, idcount);
04622 return;
04623
04624 default:
04625 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
04626 return;
04627 }
04628 }
04629
04630
04631 static void FeatureNewName(ByteReader *buf)
04632 {
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648
04649 bool new_scheme = _cur_grffile->grf_version >= 7;
04650
04651 uint8 feature = buf->ReadByte();
04652 uint8 lang = buf->ReadByte();
04653 uint8 num = buf->ReadByte();
04654 bool generic = HasBit(lang, 7);
04655 uint16 id;
04656 if (generic) {
04657 id = buf->ReadWord();
04658 } else if (feature <= GSF_AIRCRAFT) {
04659 id = buf->ReadExtendedByte();
04660 } else {
04661 id = buf->ReadByte();
04662 }
04663
04664 ClrBit(lang, 7);
04665
04666 uint16 endid = id + num;
04667
04668 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
04669 id, endid, feature, lang);
04670
04671 for (; id < endid && buf->HasData(); id++) {
04672 const char *name = buf->ReadString();
04673 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
04674
04675 switch (feature) {
04676 case GSF_TRAINS:
04677 case GSF_ROADVEHICLES:
04678 case GSF_SHIPS:
04679 case GSF_AIRCRAFT:
04680 if (!generic) {
04681 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
04682 if (e == NULL) break;
04683 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
04684 e->info.string_id = string;
04685 } else {
04686 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04687 }
04688 break;
04689
04690 case GSF_INDUSTRIES: {
04691 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04692 break;
04693 }
04694
04695 case GSF_HOUSES:
04696 default:
04697 switch (GB(id, 8, 8)) {
04698 case 0xC4:
04699 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04700 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04701 } else {
04702 StationClassID cls_id = _cur_grffile->stations[GB(id, 0, 8)]->cls_id;
04703 StationClass::SetName(cls_id, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
04704 }
04705 break;
04706
04707 case 0xC5:
04708 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04709 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04710 } else {
04711 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04712 }
04713 break;
04714
04715 case 0xC7:
04716 if (_cur_grffile->airtspec == NULL || _cur_grffile->airtspec[GB(id, 0, 8)] == NULL) {
04717 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
04718 } else {
04719 _cur_grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04720 }
04721 break;
04722
04723 case 0xC9:
04724 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
04725 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
04726 } else {
04727 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04728 }
04729 break;
04730
04731 case 0xD0:
04732 case 0xD1:
04733 case 0xD2:
04734 case 0xD3:
04735 case 0xDC:
04736 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04737 break;
04738
04739 default:
04740 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
04741 break;
04742 }
04743 break;
04744 }
04745 }
04746 }
04747
04756 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
04757 {
04758
04759 if (offset >= max_sprites) {
04760 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
04761 uint orig_num = num;
04762 num = 0;
04763 return orig_num;
04764 }
04765
04766 if (offset + num > max_sprites) {
04767 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
04768 uint orig_num = num;
04769 num = max(max_sprites - offset, 0);
04770 return orig_num - num;
04771 }
04772
04773 return 0;
04774 }
04775
04776
04778 enum Action5BlockType {
04779 A5BLOCK_FIXED,
04780 A5BLOCK_ALLOW_OFFSET,
04781 A5BLOCK_INVALID,
04782 };
04784 struct Action5Type {
04785 Action5BlockType block_type;
04786 SpriteID sprite_base;
04787 uint16 min_sprites;
04788 uint16 max_sprites;
04789 const char *name;
04790 };
04791
04793 static const Action5Type _action5_types[] = {
04794
04795 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
04796 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
04797 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
04798 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
04799 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
04800 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
04801 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
04802 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
04803 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
04804 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
04805 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
04806 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
04807 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
04808 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
04809 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
04810 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
04811 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
04812 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
04813 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
04814 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
04815 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
04816 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
04817 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
04818 };
04819
04820
04821 static void GraphicsNew(ByteReader *buf)
04822 {
04823
04824
04825
04826
04827
04828
04829
04830 uint8 type = buf->ReadByte();
04831 uint16 num = buf->ReadExtendedByte();
04832 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
04833 ClrBit(type, 7);
04834
04835 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
04836
04837
04838 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
04839 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
04840 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
04841 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
04842 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
04843 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
04844 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
04845 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
04846 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
04847 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
04848 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
04849 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
04850 return;
04851 }
04852
04853
04854 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
04855 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
04856 _skip_sprites = num;
04857 return;
04858 }
04859
04860 const Action5Type *action5_type = &_action5_types[type];
04861
04862
04863 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
04864 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
04865 offset = 0;
04866 }
04867
04868
04869
04870 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
04871 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);
04872 _skip_sprites = num;
04873 return;
04874 }
04875
04876
04877 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
04878 SpriteID replace = action5_type->sprite_base + offset;
04879
04880
04881 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);
04882
04883 for (; num > 0; num--) {
04884 _nfo_line++;
04885 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
04886 }
04887
04888 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
04889
04890 _skip_sprites = skip_num;
04891 }
04892
04893
04894 static void SkipAct5(ByteReader *buf)
04895 {
04896
04897 buf->ReadByte();
04898
04899
04900 _skip_sprites = buf->ReadExtendedByte();
04901
04902 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
04903 }
04904
04910 void CheckForMissingSprites()
04911 {
04912
04913
04914 bool missing = false;
04915 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
04916 const Action5Type *type = &_action5_types[i];
04917 if (type->block_type == A5BLOCK_INVALID) continue;
04918
04919 for (uint j = 0; j < type->max_sprites; j++) {
04920 if (!SpriteExists(type->sprite_base + j)) {
04921 DEBUG(grf, 0, "%s sprites are missing", type->name);
04922 missing = true;
04923
04924 break;
04925 }
04926 }
04927 }
04928
04929 if (missing) {
04930 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
04931 }
04932 }
04933
04944 bool GetGlobalVariable(byte param, uint32 *value)
04945 {
04946 switch (param) {
04947 case 0x00:
04948 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
04949 return true;
04950
04951 case 0x01:
04952 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
04953 return true;
04954
04955 case 0x02: {
04956 YearMonthDay ymd;
04957 ConvertDateToYMD(_date, &ymd);
04958 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
04959 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
04960 return true;
04961 }
04962
04963 case 0x03:
04964 *value = _settings_game.game_creation.landscape;
04965 return true;
04966
04967 case 0x06:
04968 *value = _settings_game.vehicle.road_side << 4;
04969 return true;
04970
04971 case 0x09:
04972 *value = _date_fract * 885;
04973 return true;
04974
04975 case 0x0A:
04976 *value = _tick_counter;
04977 return true;
04978
04979 case 0x0B: {
04980 uint major = 2;
04981 uint minor = 6;
04982 uint revision = 1;
04983 uint build = 1382;
04984 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
04985 return true;
04986 }
04987
04988 case 0x0D:
04989 *value = _cur_grfconfig->palette & GRFP_USE_MASK;
04990 return true;
04991
04992 case 0x0E:
04993 *value = _cur_grffile->traininfo_vehicle_pitch;
04994 return true;
04995
04996 case 0x0F:
04997 *value = 0;
04998 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
04999 if (_settings_game.vehicle.disable_elrails) {
05000
05001 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05002 } else {
05003 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05004
05005 }
05006 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05007 return true;
05008
05009 case 0x11:
05010 *value = 0;
05011 return true;
05012
05013 case 0x12:
05014 *value = _game_mode;
05015 return true;
05016
05017
05018
05019
05020
05021
05022
05023 case 0x1A:
05024 *value = UINT_MAX;
05025 return true;
05026
05027 case 0x1B:
05028 *value = GB(_display_opt, 0, 6);
05029 return true;
05030
05031 case 0x1D:
05032 *value = 1;
05033 return true;
05034
05035 case 0x1E:
05036 *value = _misc_grf_features;
05037
05038
05039 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05040 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05041 return true;
05042
05043
05044
05045 case 0x20:
05046 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
05047 return true;
05048
05049 case 0x21:
05050 *value = _openttd_newgrf_version;
05051 return true;
05052
05053 case 0x22:
05054 *value = _settings_game.difficulty.diff_level;
05055 return true;
05056
05057 case 0x23:
05058 *value = _date;
05059 return true;
05060
05061 case 0x24:
05062 *value = _cur_year;
05063 return true;
05064
05065 default: return false;
05066 }
05067 }
05068
05069 static uint32 GetParamVal(byte param, uint32 *cond_val)
05070 {
05071
05072 uint32 value;
05073 if (GetGlobalVariable(param - 0x80, &value)) return value;
05074
05075
05076 switch (param) {
05077 case 0x84: {
05078 uint32 res = 0;
05079
05080 if (_cur_stage > GLS_INIT) SetBit(res, 0);
05081 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
05082 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
05083 return res;
05084 }
05085
05086 case 0x85:
05087 if (cond_val == NULL) {
05088
05089 return 0;
05090 } else {
05091 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05092 *cond_val %= 0x20;
05093 return param_val;
05094 }
05095
05096 case 0x88:
05097 return 0;
05098
05099
05100
05101 default:
05102
05103 if (param < 0x80) return _cur_grffile->GetParam(param);
05104
05105
05106 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05107 return UINT_MAX;
05108 }
05109 }
05110
05111
05112 static void CfgApply(ByteReader *buf)
05113 {
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126 size_t pos = FioGetPos();
05127 uint16 num = FioReadWord();
05128 uint8 type = FioReadByte();
05129 byte *preload_sprite = NULL;
05130
05131
05132 if (type == 0xFF) {
05133 preload_sprite = MallocT<byte>(num);
05134 FioReadBlock(preload_sprite, num);
05135 }
05136
05137
05138 FioSeekTo(pos, SEEK_SET);
05139
05140 if (type != 0xFF) {
05141 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05142 free(preload_sprite);
05143 return;
05144 }
05145
05146 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line + 1);
05147 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05148 if (it != _grf_line_to_action6_sprite_override.end()) {
05149 free(preload_sprite);
05150 preload_sprite = _grf_line_to_action6_sprite_override[location];
05151 } else {
05152 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05153 }
05154
05155
05156
05157 for (;;) {
05158 uint i;
05159 uint param_num;
05160 uint param_size;
05161 uint offset;
05162 bool add_value;
05163
05164
05165 param_num = buf->ReadByte();
05166 if (param_num == 0xFF) break;
05167
05168
05169
05170 param_size = buf->ReadByte();
05171
05172
05173
05174 add_value = HasBit(param_size, 7);
05175 param_size = GB(param_size, 0, 7);
05176
05177
05178 offset = buf->ReadExtendedByte();
05179
05180
05181
05182 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
05183 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05184 break;
05185 }
05186
05187 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05188
05189 bool carry = false;
05190 for (i = 0; i < param_size && offset + i < num; i++) {
05191 uint32 value = GetParamVal(param_num + i / 4, NULL);
05192
05193
05194 if (i % 4 == 0) carry = false;
05195
05196 if (add_value) {
05197 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05198 preload_sprite[offset + i] = GB(new_value, 0, 8);
05199
05200 carry = new_value >= 256;
05201 } else {
05202 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05203 }
05204 }
05205 }
05206 }
05207
05217 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05218 {
05219 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05220 error->data = strdup(_cur_grfconfig->GetName());
05221 }
05222
05223
05224
05225 static void SkipIf(ByteReader *buf)
05226 {
05227
05228
05229
05230
05231
05232
05233
05234
05235 uint32 cond_val = 0;
05236 uint32 mask = 0;
05237 bool result;
05238
05239 uint8 param = buf->ReadByte();
05240 uint8 paramsize = buf->ReadByte();
05241 uint8 condtype = buf->ReadByte();
05242
05243 if (condtype < 2) {
05244
05245 paramsize = 1;
05246 }
05247
05248 switch (paramsize) {
05249 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05250 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05251 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05252 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05253 default: break;
05254 }
05255
05256 if (param < 0x80 && _cur_grffile->param_end <= param) {
05257 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05258 return;
05259 }
05260
05261 uint32 param_val = GetParamVal(param, &cond_val);
05262
05263 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05264
05265
05266
05267
05268
05269
05270
05271
05272
05273 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05274
05275
05276 GRFConfig *c = GetGRFConfig(cond_val, mask);
05277
05278 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05279 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05280 c = NULL;
05281 }
05282
05283 if (condtype != 10 && c == NULL) {
05284 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05285 return;
05286 }
05287
05288 switch (condtype) {
05289
05290 case 0x06:
05291 result = c->status == GCS_ACTIVATED;
05292 break;
05293
05294 case 0x07:
05295 result = c->status != GCS_ACTIVATED;
05296 break;
05297
05298 case 0x08:
05299 result = c->status == GCS_INITIALISED;
05300 break;
05301
05302 case 0x09:
05303 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05304 break;
05305
05306 case 0x0A:
05307
05308 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05309 break;
05310
05311 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05312 }
05313 } else {
05314
05315 switch (condtype) {
05316 case 0x00: result = !!(param_val & (1 << cond_val));
05317 break;
05318 case 0x01: result = !(param_val & (1 << cond_val));
05319 break;
05320 case 0x02: result = (param_val & mask) == cond_val;
05321 break;
05322 case 0x03: result = (param_val & mask) != cond_val;
05323 break;
05324 case 0x04: result = (param_val & mask) < cond_val;
05325 break;
05326 case 0x05: result = (param_val & mask) > cond_val;
05327 break;
05328 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05329 break;
05330 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05331 break;
05332 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
05333 break;
05334 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
05335 break;
05336
05337 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
05338 }
05339 }
05340
05341 if (!result) {
05342 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
05343 return;
05344 }
05345
05346 uint8 numsprites = buf->ReadByte();
05347
05348
05349
05350
05351
05352 GRFLabel *choice = NULL;
05353 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
05354 if (label->label != numsprites) continue;
05355
05356
05357 if (choice == NULL) choice = label;
05358
05359 if (label->nfo_line > _nfo_line) {
05360 choice = label;
05361 break;
05362 }
05363 }
05364
05365 if (choice != NULL) {
05366 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
05367 FioSeekTo(choice->pos, SEEK_SET);
05368 _nfo_line = choice->nfo_line;
05369 return;
05370 }
05371
05372 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
05373 _skip_sprites = numsprites;
05374 if (_skip_sprites == 0) {
05375
05376
05377
05378 _skip_sprites = -1;
05379
05380
05381 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
05382 DisableGrf();
05383 }
05384 }
05385 }
05386
05387
05388
05389 static void ScanInfo(ByteReader *buf)
05390 {
05391 uint8 grf_version = buf->ReadByte();
05392 uint32 grfid = buf->ReadDWord();
05393 const char *name = buf->ReadString();
05394
05395 _cur_grfconfig->ident.grfid = grfid;
05396
05397 if (grf_version < 2 || grf_version > 7) {
05398 SetBit(_cur_grfconfig->flags, GCF_INVALID);
05399 DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur_grfconfig->filename, name, BSWAP32(grfid), grf_version);
05400 }
05401
05402
05403 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
05404
05405 AddGRFTextToList(&_cur_grfconfig->name->text, 0x7F, grfid, name);
05406
05407 if (buf->HasData()) {
05408 const char *info = buf->ReadString();
05409 AddGRFTextToList(&_cur_grfconfig->info->text, 0x7F, grfid, info);
05410 }
05411
05412
05413 _skip_sprites = -1;
05414 }
05415
05416
05417 static void GRFInfo(ByteReader *buf)
05418 {
05419
05420
05421
05422
05423
05424
05425
05426 uint8 version = buf->ReadByte();
05427 uint32 grfid = buf->ReadDWord();
05428 const char *name = buf->ReadString();
05429
05430 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
05431 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
05432 return;
05433 }
05434
05435 if (_cur_grffile->grfid != grfid) {
05436 DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur_grffile->grfid), BSWAP32(grfid));
05437 _cur_grffile->grfid = grfid;
05438 }
05439
05440 _cur_grffile->grf_version = version;
05441 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
05442
05443
05444 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur_grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur_grfconfig->version);
05445 }
05446
05447
05448 static void SpriteReplace(ByteReader *buf)
05449 {
05450
05451
05452
05453
05454
05455
05456
05457
05458 uint8 num_sets = buf->ReadByte();
05459
05460 for (uint i = 0; i < num_sets; i++) {
05461 uint8 num_sprites = buf->ReadByte();
05462 uint16 first_sprite = buf->ReadWord();
05463
05464 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
05465 i, num_sprites, first_sprite
05466 );
05467
05468 for (uint j = 0; j < num_sprites; j++) {
05469 int load_index = first_sprite + j;
05470 _nfo_line++;
05471 LoadNextSprite(load_index, _file_index, _nfo_line);
05472
05473
05474
05475 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
05476 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
05477 }
05478 }
05479 }
05480 }
05481
05482
05483 static void SkipActA(ByteReader *buf)
05484 {
05485 uint8 num_sets = buf->ReadByte();
05486
05487 for (uint i = 0; i < num_sets; i++) {
05488
05489 _skip_sprites += buf->ReadByte();
05490
05491 buf->ReadWord();
05492 }
05493
05494 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
05495 }
05496
05497
05498 static void GRFLoadError(ByteReader *buf)
05499 {
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515 static const StringID msgstr[] = {
05516 STR_NEWGRF_ERROR_VERSION_NUMBER,
05517 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
05518 STR_NEWGRF_ERROR_UNSET_SWITCH,
05519 STR_NEWGRF_ERROR_INVALID_PARAMETER,
05520 STR_NEWGRF_ERROR_LOAD_BEFORE,
05521 STR_NEWGRF_ERROR_LOAD_AFTER,
05522 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
05523 };
05524
05525 static const StringID sevstr[] = {
05526 STR_NEWGRF_ERROR_MSG_INFO,
05527 STR_NEWGRF_ERROR_MSG_WARNING,
05528 STR_NEWGRF_ERROR_MSG_ERROR,
05529 STR_NEWGRF_ERROR_MSG_FATAL
05530 };
05531
05532
05533 if (_cur_grfconfig->error != NULL) return;
05534
05535 byte severity = buf->ReadByte();
05536 byte lang = buf->ReadByte();
05537 byte message_id = buf->ReadByte();
05538
05539
05540 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
05541
05542
05543
05544 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
05545 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
05546 return;
05547 }
05548 ClrBit(severity, 7);
05549
05550 if (severity >= lengthof(sevstr)) {
05551 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
05552 severity = 2;
05553 } else if (severity == 3) {
05554
05555
05556 DisableGrf();
05557 }
05558
05559 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
05560 grfmsg(7, "GRFLoadError: Invalid message id.");
05561 return;
05562 }
05563
05564 if (buf->Remaining() <= 1) {
05565 grfmsg(7, "GRFLoadError: No message data supplied.");
05566 return;
05567 }
05568
05569 GRFError *error = new GRFError(sevstr[severity]);
05570
05571 if (message_id == 0xFF) {
05572
05573 if (buf->HasData()) {
05574 const char *message = buf->ReadString();
05575
05576 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, message);
05577 } else {
05578 grfmsg(7, "GRFLoadError: No custom message supplied.");
05579 error->custom_message = strdup("");
05580 }
05581 } else {
05582 error->message = msgstr[message_id];
05583 }
05584
05585 if (buf->HasData()) {
05586 const char *data = buf->ReadString();
05587
05588 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, data);
05589 } else {
05590 grfmsg(7, "GRFLoadError: No message data supplied.");
05591 error->data = strdup("");
05592 }
05593
05594
05595 uint i = 0;
05596 for (; i < 2 && buf->HasData(); i++) {
05597 uint param_number = buf->ReadByte();
05598 error->param_value[i] = _cur_grffile->GetParam(param_number);
05599 }
05600 error->num_params = i;
05601
05602 _cur_grfconfig->error = error;
05603 }
05604
05605
05606 static void GRFComment(ByteReader *buf)
05607 {
05608
05609
05610
05611
05612 if (!buf->HasData()) return;
05613
05614 const char *text = buf->ReadString();
05615 grfmsg(2, "GRFComment: %s", text);
05616 }
05617
05618
05619 static void SafeParamSet(ByteReader *buf)
05620 {
05621 uint8 target = buf->ReadByte();
05622
05623
05624 if (target < 0x80) return;
05625
05626
05627
05628
05629
05630
05631 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05632
05633
05634 _skip_sprites = -1;
05635 }
05636
05637
05638 static uint32 GetPatchVariable(uint8 param)
05639 {
05640 switch (param) {
05641
05642 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
05643
05644
05645 case 0x0E: return _settings_game.vehicle.freight_trains;
05646
05647
05648 case 0x0F: return 0;
05649
05650
05651
05652
05653 case 0x10:
05654 switch (_settings_game.vehicle.plane_speed) {
05655 default:
05656 case 4: return 1;
05657 case 3: return 2;
05658 case 2: return 2;
05659 case 1: return 4;
05660 }
05661
05662
05663
05664 case 0x11: return SPR_2CCMAP_BASE;
05665
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675
05676
05677 case 0x13: {
05678 byte map_bits = 0;
05679 byte log_X = MapLogX() - 6;
05680 byte log_Y = MapLogY() - 6;
05681 byte max_edge = max(log_X, log_Y);
05682
05683 if (log_X == log_Y) {
05684 SetBit(map_bits, 0);
05685 } else {
05686 if (max_edge == log_Y) SetBit(map_bits, 1);
05687 }
05688
05689 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
05690 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
05691 }
05692
05693 default:
05694 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
05695 return 0;
05696 }
05697 }
05698
05699
05700 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
05701 {
05702 uint start = 0;
05703 uint size = 0;
05704
05705 if (op == 6) {
05706
05707 return grm[_cur_grffile->GetParam(target)];
05708 }
05709
05710
05711 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
05712
05713 for (uint i = start; i < num_ids; i++) {
05714 if (grm[i] == 0) {
05715 size++;
05716 } else {
05717 if (op == 2 || op == 3) break;
05718 start = i + 1;
05719 size = 0;
05720 }
05721
05722 if (size == count) break;
05723 }
05724
05725 if (size == count) {
05726
05727 if (op == 0 || op == 3) {
05728 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
05729 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
05730 }
05731 return start;
05732 }
05733
05734
05735 if (op != 4 && op != 5) {
05736
05737 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
05738 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05739 return UINT_MAX;
05740 }
05741
05742 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
05743 return UINT_MAX;
05744 }
05745
05746
05747
05748 static void ParamSet(ByteReader *buf)
05749 {
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772 uint8 target = buf->ReadByte();
05773 uint8 oper = buf->ReadByte();
05774 uint32 src1 = buf->ReadByte();
05775 uint32 src2 = buf->ReadByte();
05776
05777 uint32 data = 0;
05778 if (buf->Remaining() >= 4) data = buf->ReadDWord();
05779
05780
05781
05782
05783
05784
05785
05786 if (HasBit(oper, 7)) {
05787 if (target < 0x80 && target < _cur_grffile->param_end) {
05788 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
05789 return;
05790 }
05791
05792 oper = GB(oper, 0, 7);
05793 }
05794
05795 if (src2 == 0xFE) {
05796 if (GB(data, 0, 8) == 0xFF) {
05797 if (data == 0x0000FFFF) {
05798
05799 src1 = GetPatchVariable(src1);
05800 } else {
05801
05802 uint8 op = src1;
05803 uint8 feature = GB(data, 8, 8);
05804 uint16 count = GB(data, 16, 16);
05805
05806 if (_cur_stage == GLS_RESERVE) {
05807 if (feature == 0x08) {
05808
05809 if (op == 0) {
05810
05811 if (_cur_spriteid + count >= 16384) {
05812 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
05813 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05814 return;
05815 }
05816
05817
05818 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
05819 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
05820 _cur_spriteid += count;
05821 }
05822 }
05823
05824 src1 = 0;
05825 } else if (_cur_stage == GLS_ACTIVATION) {
05826 switch (feature) {
05827 case 0x00:
05828 case 0x01:
05829 case 0x02:
05830 case 0x03:
05831 if (!_settings_game.vehicle.dynamic_engines) {
05832 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
05833 if (_skip_sprites == -1) return;
05834 } else {
05835
05836 switch (op) {
05837 case 2:
05838 case 3:
05839 src1 = _cur_grffile->GetParam(target);
05840 break;
05841
05842 default:
05843 src1 = 0;
05844 break;
05845 }
05846 }
05847 break;
05848
05849 case 0x08:
05850 switch (op) {
05851 case 0:
05852
05853 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
05854 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
05855 break;
05856
05857 case 1:
05858 src1 = _cur_spriteid;
05859 break;
05860
05861 default:
05862 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
05863 return;
05864 }
05865 break;
05866
05867 case 0x0B:
05868
05869 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
05870 if (_skip_sprites == -1) return;
05871 break;
05872
05873 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
05874 }
05875 } else {
05876
05877 src1 = 0;
05878 }
05879 }
05880 } else {
05881
05882 const GRFFile *file = GetFileByGRFID(data);
05883 GRFConfig *c = GetGRFConfig(data);
05884 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05885
05886 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05887 src1 = 0;
05888 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
05889 src1 = 0;
05890 } else if (src1 == 0xFE) {
05891 src1 = c->version;
05892 } else {
05893 src1 = file->GetParam(src1);
05894 }
05895 }
05896 } else {
05897
05898
05899
05900
05901
05902 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
05903 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
05904 }
05905
05906
05907
05908
05909
05910
05911
05912 uint32 res;
05913 switch (oper) {
05914 case 0x00:
05915 res = src1;
05916 break;
05917
05918 case 0x01:
05919 res = src1 + src2;
05920 break;
05921
05922 case 0x02:
05923 res = src1 - src2;
05924 break;
05925
05926 case 0x03:
05927 res = src1 * src2;
05928 break;
05929
05930 case 0x04:
05931 res = (int32)src1 * (int32)src2;
05932 break;
05933
05934 case 0x05:
05935 if ((int32)src2 < 0) {
05936 res = src1 >> -(int32)src2;
05937 } else {
05938 res = src1 << src2;
05939 }
05940 break;
05941
05942 case 0x06:
05943 if ((int32)src2 < 0) {
05944 res = (int32)src1 >> -(int32)src2;
05945 } else {
05946 res = (int32)src1 << src2;
05947 }
05948 break;
05949
05950 case 0x07:
05951 res = src1 & src2;
05952 break;
05953
05954 case 0x08:
05955 res = src1 | src2;
05956 break;
05957
05958 case 0x09:
05959 if (src2 == 0) {
05960 res = src1;
05961 } else {
05962 res = src1 / src2;
05963 }
05964 break;
05965
05966 case 0x0A:
05967 if (src2 == 0) {
05968 res = src1;
05969 } else {
05970 res = (int32)src1 / (int32)src2;
05971 }
05972 break;
05973
05974 case 0x0B:
05975 if (src2 == 0) {
05976 res = src1;
05977 } else {
05978 res = src1 % src2;
05979 }
05980 break;
05981
05982 case 0x0C:
05983 if (src2 == 0) {
05984 res = src1;
05985 } else {
05986 res = (int32)src1 % (int32)src2;
05987 }
05988 break;
05989
05990 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
05991 }
05992
05993 switch (target) {
05994 case 0x8E:
05995 _cur_grffile->traininfo_vehicle_pitch = res;
05996 break;
05997
05998 case 0x8F: {
05999 extern RailtypeInfo _railtypes[RAILTYPE_END];
06000 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06001 if (_settings_game.vehicle.disable_elrails) {
06002 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06003 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06004 } else {
06005 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06006 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06007 }
06008 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06009 break;
06010 }
06011
06012
06013 case 0x93:
06014 case 0x94:
06015 case 0x95:
06016 case 0x96:
06017 case 0x97:
06018 case 0x99:
06019 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06020 break;
06021
06022 case 0x9E:
06023 _misc_grf_features = res;
06024
06025
06026 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06027
06028
06029 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
06030 break;
06031
06032 case 0x9F:
06033 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06034 break;
06035
06036 default:
06037 if (target < 0x80) {
06038 _cur_grffile->param[target] = res;
06039
06040 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
06041 } else {
06042 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06043 }
06044 break;
06045 }
06046 }
06047
06048
06049 static void SafeGRFInhibit(ByteReader *buf)
06050 {
06051
06052
06053
06054
06055
06056 uint8 num = buf->ReadByte();
06057
06058 for (uint i = 0; i < num; i++) {
06059 uint32 grfid = buf->ReadDWord();
06060
06061
06062 if (grfid != _cur_grfconfig->ident.grfid) {
06063 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06064
06065
06066 _skip_sprites = -1;
06067
06068 return;
06069 }
06070 }
06071 }
06072
06073
06074 static void GRFInhibit(ByteReader *buf)
06075 {
06076
06077
06078
06079
06080
06081 uint8 num = buf->ReadByte();
06082
06083 for (uint i = 0; i < num; i++) {
06084 uint32 grfid = buf->ReadDWord();
06085 GRFConfig *file = GetGRFConfig(grfid);
06086
06087
06088 if (file != NULL && file != _cur_grfconfig) {
06089 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06090 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06091 error->data = strdup(_cur_grfconfig->GetName());
06092 }
06093 }
06094 }
06095
06096
06097 static void FeatureTownName(ByteReader *buf)
06098 {
06099
06100
06101
06102
06103
06104
06105
06106 uint32 grfid = _cur_grffile->grfid;
06107
06108 GRFTownName *townname = AddGRFTownName(grfid);
06109
06110 byte id = buf->ReadByte();
06111 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06112
06113 if (HasBit(id, 7)) {
06114
06115 ClrBit(id, 7);
06116 bool new_scheme = _cur_grffile->grf_version >= 7;
06117
06118 byte lang = buf->ReadByte();
06119
06120 byte nb_gen = townname->nb_gen;
06121 do {
06122 ClrBit(lang, 7);
06123
06124 const char *name = buf->ReadString();
06125
06126 char *lang_name = TranslateTTDPatchCodes(grfid, lang, name);
06127 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06128 free(lang_name);
06129
06130 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
06131
06132 lang = buf->ReadByte();
06133 } while (lang != 0);
06134 townname->id[nb_gen] = id;
06135 townname->nb_gen++;
06136 }
06137
06138 byte nb = buf->ReadByte();
06139 grfmsg(6, "FeatureTownName: %u parts", nb);
06140
06141 townname->nbparts[id] = nb;
06142 townname->partlist[id] = CallocT<NamePartList>(nb);
06143
06144 for (int i = 0; i < nb; i++) {
06145 byte nbtext = buf->ReadByte();
06146 townname->partlist[id][i].bitstart = buf->ReadByte();
06147 townname->partlist[id][i].bitcount = buf->ReadByte();
06148 townname->partlist[id][i].maxprob = 0;
06149 townname->partlist[id][i].partcount = nbtext;
06150 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06151 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);
06152
06153 for (int j = 0; j < nbtext; j++) {
06154 byte prob = buf->ReadByte();
06155
06156 if (HasBit(prob, 7)) {
06157 byte ref_id = buf->ReadByte();
06158
06159 if (townname->nbparts[ref_id] == 0) {
06160 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06161 DelGRFTownName(grfid);
06162 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06163 return;
06164 }
06165
06166 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06167 townname->partlist[id][i].parts[j].data.id = ref_id;
06168 } else {
06169 const char *text = buf->ReadString();
06170 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, text);
06171 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06172 }
06173 townname->partlist[id][i].parts[j].prob = prob;
06174 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06175 }
06176 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06177 }
06178 }
06179
06180
06181 static void DefineGotoLabel(ByteReader *buf)
06182 {
06183
06184
06185
06186
06187
06188 byte nfo_label = buf->ReadByte();
06189
06190 GRFLabel *label = MallocT<GRFLabel>(1);
06191 label->label = nfo_label;
06192 label->nfo_line = _nfo_line;
06193 label->pos = FioGetPos();
06194 label->next = NULL;
06195
06196
06197 if (_cur_grffile->label == NULL) {
06198 _cur_grffile->label = label;
06199 } else {
06200
06201 GRFLabel *l;
06202 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
06203 l->next = label;
06204 }
06205
06206 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06207 }
06208
06209
06210 static void GRFSound(ByteReader *buf)
06211 {
06212
06213
06214
06215
06216 uint16 num = buf->ReadWord();
06217
06218 _grf_data_blocks = num;
06219 _grf_data_type = GDT_SOUND;
06220
06221 if (_cur_grffile->sound_offset == 0) {
06222 _cur_grffile->sound_offset = GetNumSounds();
06223 _cur_grffile->num_sounds = num;
06224 }
06225 }
06226
06227
06228 static void SkipAct11(ByteReader *buf)
06229 {
06230
06231
06232
06233
06234 _skip_sprites = buf->ReadWord();
06235
06236 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
06237 }
06238
06239 static void ImportGRFSound(ByteReader *buf)
06240 {
06241 const GRFFile *file;
06242 SoundEntry *sound = AllocateSound();
06243 uint32 grfid = buf->ReadDWord();
06244 SoundID sound_id = buf->ReadWord();
06245
06246 file = GetFileByGRFID(grfid);
06247 if (file == NULL || file->sound_offset == 0) {
06248 grfmsg(1, "ImportGRFSound: Source file not available");
06249 return;
06250 }
06251
06252 if (sound_id >= file->num_sounds) {
06253 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06254 return;
06255 }
06256
06257 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06258
06259 *sound = *GetSound(file->sound_offset + sound_id);
06260
06261
06262 sound->volume = 128;
06263 sound->priority = 0;
06264 }
06265
06266
06267 static void GRFImportBlock(ByteReader *buf)
06268 {
06269 if (_grf_data_blocks == 0) {
06270 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
06271 return;
06272 }
06273
06274 _grf_data_blocks--;
06275
06276
06277
06278 if (buf->ReadByte() != _grf_data_type) {
06279 grfmsg(1, "GRFImportBlock: Import type mismatch");
06280 }
06281
06282 switch (_grf_data_type) {
06283 case GDT_SOUND: ImportGRFSound(buf); break;
06284 default: NOT_REACHED();
06285 }
06286 }
06287
06288 static void LoadGRFSound(ByteReader *buf)
06289 {
06290
06291
06292 SoundEntry *sound = AllocateSound();
06293
06294 if (buf->ReadDWord() != BSWAP32('RIFF')) {
06295 grfmsg(1, "LoadGRFSound: Missing RIFF header");
06296 return;
06297 }
06298
06299 uint32 total_size = buf->ReadDWord();
06300 if (total_size > buf->Remaining()) {
06301 grfmsg(1, "LoadGRFSound: RIFF was truncated");
06302 return;
06303 }
06304
06305 if (buf->ReadDWord() != BSWAP32('WAVE')) {
06306 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
06307 return;
06308 }
06309
06310 while (total_size >= 8) {
06311 uint32 tag = buf->ReadDWord();
06312 uint32 size = buf->ReadDWord();
06313 total_size -= 8;
06314 if (total_size < size) {
06315 grfmsg(1, "LoadGRFSound: Invalid RIFF");
06316 return;
06317 }
06318 total_size -= size;
06319
06320 switch (tag) {
06321 case ' tmf':
06322
06323 if (size < 16 || buf->ReadWord() != 1) {
06324 grfmsg(1, "LoadGRFSound: Invalid audio format");
06325 return;
06326 }
06327 sound->channels = buf->ReadWord();
06328 sound->rate = buf->ReadDWord();
06329 buf->ReadDWord();
06330 buf->ReadWord();
06331 sound->bits_per_sample = buf->ReadWord();
06332
06333
06334 size -= 16;
06335 break;
06336
06337 case 'atad':
06338 sound->file_size = size;
06339 sound->file_offset = FioGetPos() - buf->Remaining();
06340 sound->file_slot = _file_index;
06341
06342
06343 sound->volume = 0x80;
06344 sound->priority = 0;
06345
06346 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
06347 return;
06348
06349 default:
06350
06351 break;
06352 }
06353
06354
06355 for (; size > 0; size--) buf->ReadByte();
06356 }
06357
06358 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
06359
06360
06361 MemSetT(sound, 0);
06362 }
06363
06364
06365 static void LoadFontGlyph(ByteReader *buf)
06366 {
06367
06368
06369
06370
06371
06372
06373
06374 uint8 num_def = buf->ReadByte();
06375
06376 for (uint i = 0; i < num_def; i++) {
06377 FontSize size = (FontSize)buf->ReadByte();
06378 uint8 num_char = buf->ReadByte();
06379 uint16 base_char = buf->ReadWord();
06380
06381 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
06382
06383 for (uint c = 0; c < num_char; c++) {
06384 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
06385 _nfo_line++;
06386 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
06387 }
06388 }
06389 }
06390
06391
06392 static void SkipAct12(ByteReader *buf)
06393 {
06394
06395
06396
06397
06398
06399
06400
06401 uint8 num_def = buf->ReadByte();
06402
06403 for (uint i = 0; i < num_def; i++) {
06404
06405 buf->ReadByte();
06406
06407
06408 _skip_sprites += buf->ReadByte();
06409
06410
06411 buf->ReadWord();
06412 }
06413
06414 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
06415 }
06416
06417
06418 static void TranslateGRFStrings(ByteReader *buf)
06419 {
06420
06421
06422
06423
06424
06425
06426
06427 uint32 grfid = buf->ReadDWord();
06428 const GRFConfig *c = GetGRFConfig(grfid);
06429 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
06430 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
06431 return;
06432 }
06433
06434 if (c->status == GCS_INITIALISED) {
06435
06436
06437 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
06438
06439 char tmp[256];
06440 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
06441 error->data = strdup(tmp);
06442
06443 return;
06444 }
06445
06446 byte num_strings = buf->ReadByte();
06447 uint16 first_id = buf->ReadWord();
06448
06449 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
06450 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
06451 return;
06452 }
06453
06454 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
06455 const char *string = buf->ReadString();
06456
06457 if (StrEmpty(string)) {
06458 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
06459 continue;
06460 }
06461
06462
06463
06464
06465
06466
06467 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
06468 }
06469 }
06470
06472 static bool ChangeGRFName(byte langid, const char *str)
06473 {
06474 AddGRFTextToList(&_cur_grfconfig->name->text, langid, _cur_grfconfig->ident.grfid, str);
06475 return true;
06476 }
06477
06479 static bool ChangeGRFDescription(byte langid, const char *str)
06480 {
06481 AddGRFTextToList(&_cur_grfconfig->info->text, langid, _cur_grfconfig->ident.grfid, str);
06482 return true;
06483 }
06484
06486 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
06487 {
06488 if (len != 1) {
06489 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
06490 buf->Skip(len);
06491 } else {
06492 _cur_grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur_grfconfig->param));
06493 }
06494 return true;
06495 }
06496
06498 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
06499 {
06500 if (len != 1) {
06501 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
06502 buf->Skip(len);
06503 } else {
06504 char data = buf->ReadByte();
06505 GRFPalette pal = GRFP_GRF_UNSET;
06506 switch (data) {
06507 case '*':
06508 case 'A': pal = GRFP_GRF_ANY; break;
06509 case 'W': pal = GRFP_GRF_WINDOWS; break;
06510 case 'D': pal = GRFP_GRF_DOS; break;
06511 default:
06512 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
06513 break;
06514 }
06515 if (pal != GRFP_GRF_UNSET) {
06516 _cur_grfconfig->palette &= ~GRFP_GRF_MASK;
06517 _cur_grfconfig->palette |= pal;
06518 }
06519 }
06520 return true;
06521 }
06522
06524 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
06525 {
06526 if (len != 4) {
06527 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
06528 buf->Skip(len);
06529 } else {
06530
06531 _cur_grfconfig->version = _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06532 }
06533 return true;
06534 }
06535
06537 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
06538 {
06539 if (len != 4) {
06540 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
06541 buf->Skip(len);
06542 } else {
06543 _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06544 if (_cur_grfconfig->version == 0) {
06545 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
06546 _cur_grfconfig->min_loadable_version = 0;
06547 }
06548 if (_cur_grfconfig->version < _cur_grfconfig->min_loadable_version) {
06549 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur_grfconfig->min_loadable_version);
06550 _cur_grfconfig->min_loadable_version = _cur_grfconfig->version;
06551 }
06552 }
06553 return true;
06554 }
06555
06556 static GRFParameterInfo *_cur_parameter;
06557
06559 static bool ChangeGRFParamName(byte langid, const char *str)
06560 {
06561 AddGRFTextToList(&_cur_parameter->name, langid, _cur_grfconfig->ident.grfid, str);
06562 return true;
06563 }
06564
06566 static bool ChangeGRFParamDescription(byte langid, const char *str)
06567 {
06568 AddGRFTextToList(&_cur_parameter->desc, langid, _cur_grfconfig->ident.grfid, str);
06569 return true;
06570 }
06571
06573 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
06574 {
06575 if (len != 1) {
06576 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
06577 buf->Skip(len);
06578 } else {
06579 GRFParameterType type = (GRFParameterType)buf->ReadByte();
06580 if (type < PTYPE_END) {
06581 _cur_parameter->type = type;
06582 } else {
06583 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
06584 }
06585 }
06586 return true;
06587 }
06588
06590 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
06591 {
06592 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
06593 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
06594 buf->Skip(len);
06595 } else if (len != 8) {
06596 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
06597 buf->Skip(len);
06598 } else {
06599 _cur_parameter->min_value = buf->ReadDWord();
06600 _cur_parameter->max_value = buf->ReadDWord();
06601 }
06602 return true;
06603 }
06604
06606 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
06607 {
06608 if (len < 1 || len > 3) {
06609 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
06610 buf->Skip(len);
06611 } else {
06612 byte param_nr = buf->ReadByte();
06613 if (param_nr >= lengthof(_cur_grfconfig->param)) {
06614 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
06615 buf->Skip(len - 1);
06616 } else {
06617 _cur_parameter->param_nr = param_nr;
06618 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
06619 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
06620 }
06621 }
06622
06623 return true;
06624 }
06625
06627 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
06628 {
06629 if (len != 4) {
06630 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
06631 buf->Skip(len);
06632 } else {
06633 _cur_parameter->def_value = buf->ReadDWord();
06634 }
06635 _cur_grfconfig->has_param_defaults = true;
06636 return true;
06637 }
06638
06639 typedef bool (*DataHandler)(size_t, ByteReader *);
06640 typedef bool (*TextHandler)(byte, const char *str);
06641 typedef bool (*BranchHandler)(ByteReader *);
06642
06650 struct AllowedSubtags {
06652 AllowedSubtags() :
06653 id(0),
06654 type(0)
06655 {}
06656
06662 AllowedSubtags(uint32 id, DataHandler handler) :
06663 id(id),
06664 type('B')
06665 {
06666 this->handler.data = handler;
06667 }
06668
06674 AllowedSubtags(uint32 id, TextHandler handler) :
06675 id(id),
06676 type('T')
06677 {
06678 this->handler.text = handler;
06679 }
06680
06686 AllowedSubtags(uint32 id, BranchHandler handler) :
06687 id(id),
06688 type('C')
06689 {
06690 this->handler.call_handler = true;
06691 this->handler.u.branch = handler;
06692 }
06693
06699 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
06700 id(id),
06701 type('C')
06702 {
06703 this->handler.call_handler = false;
06704 this->handler.u.subtags = subtags;
06705 }
06706
06707 uint32 id;
06708 byte type;
06709 union {
06710 DataHandler data;
06711 TextHandler text;
06712 struct {
06713 union {
06714 BranchHandler branch;
06715 AllowedSubtags *subtags;
06716 } u;
06717 bool call_handler;
06718 };
06719 } handler;
06720 };
06721
06722 static bool SkipUnknownInfo(ByteReader *buf, byte type);
06723 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
06724
06731 static bool ChangeGRFParamValueNames(ByteReader *buf)
06732 {
06733 byte type = buf->ReadByte();
06734 while (type != 0) {
06735 uint32 id = buf->ReadDWord();
06736 if (type != 'T' || id > _cur_parameter->max_value) {
06737 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
06738 if (!SkipUnknownInfo(buf, type)) return false;
06739 type = buf->ReadByte();
06740 continue;
06741 }
06742
06743 byte langid = buf->ReadByte();
06744 const char *name_string = buf->ReadString();
06745
06746 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
06747 if (val_name != _cur_parameter->value_names.End()) {
06748 AddGRFTextToList(&val_name->second, langid, _cur_grfconfig->ident.grfid, name_string);
06749 } else {
06750 GRFText *list = NULL;
06751 AddGRFTextToList(&list, langid, _cur_grfconfig->ident.grfid, name_string);
06752 _cur_parameter->value_names.Insert(id, list);
06753 }
06754
06755 type = buf->ReadByte();
06756 }
06757 return true;
06758 }
06759
06760 AllowedSubtags _tags_parameters[] = {
06761 AllowedSubtags('NAME', ChangeGRFParamName),
06762 AllowedSubtags('DESC', ChangeGRFParamDescription),
06763 AllowedSubtags('TYPE', ChangeGRFParamType),
06764 AllowedSubtags('LIMI', ChangeGRFParamLimits),
06765 AllowedSubtags('MASK', ChangeGRFParamMask),
06766 AllowedSubtags('VALU', ChangeGRFParamValueNames),
06767 AllowedSubtags('DFLT', ChangeGRFParamDefault),
06768 AllowedSubtags()
06769 };
06770
06777 static bool HandleParameterInfo(ByteReader *buf)
06778 {
06779 byte type = buf->ReadByte();
06780 while (type != 0) {
06781 uint32 id = buf->ReadDWord();
06782 if (type != 'C' || id >= _cur_grfconfig->num_valid_params) {
06783 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
06784 if (!SkipUnknownInfo(buf, type)) return false;
06785 type = buf->ReadByte();
06786 continue;
06787 }
06788
06789 if (id >= _cur_grfconfig->param_info.Length()) {
06790 uint num_to_add = id - _cur_grfconfig->param_info.Length() + 1;
06791 GRFParameterInfo **newdata = _cur_grfconfig->param_info.Append(num_to_add);
06792 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
06793 }
06794 if (_cur_grfconfig->param_info[id] == NULL) {
06795 _cur_grfconfig->param_info[id] = new GRFParameterInfo(id);
06796 }
06797 _cur_parameter = _cur_grfconfig->param_info[id];
06798
06799 if (!HandleNodes(buf, _tags_parameters)) return false;
06800 type = buf->ReadByte();
06801 }
06802 return true;
06803 }
06804
06805 AllowedSubtags _tags_info[] = {
06806 AllowedSubtags('NAME', ChangeGRFName),
06807 AllowedSubtags('DESC', ChangeGRFDescription),
06808 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
06809 AllowedSubtags('PALS', ChangeGRFPalette),
06810 AllowedSubtags('VRSN', ChangeGRFVersion),
06811 AllowedSubtags('MINV', ChangeGRFMinVersion),
06812 AllowedSubtags('PARA', HandleParameterInfo),
06813 AllowedSubtags()
06814 };
06815
06816 AllowedSubtags _tags_root[] = {
06817 AllowedSubtags('INFO', _tags_info),
06818 AllowedSubtags()
06819 };
06820
06821
06826 static bool SkipUnknownInfo(ByteReader *buf, byte type)
06827 {
06828
06829 switch (type) {
06830 case 'C': {
06831 byte new_type = buf->ReadByte();
06832 while (new_type != 0) {
06833 buf->ReadDWord();
06834 if (!SkipUnknownInfo(buf, new_type)) return false;
06835 new_type = buf->ReadByte();
06836 }
06837 break;
06838 }
06839
06840 case 'T':
06841 buf->ReadByte();
06842 buf->ReadString();
06843 break;
06844
06845 case 'B': {
06846 uint16 size = buf->ReadWord();
06847 buf->Skip(size);
06848 break;
06849 }
06850
06851 default:
06852 return false;
06853 }
06854
06855 return true;
06856 }
06857
06858 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
06859 {
06860 uint i = 0;
06861 AllowedSubtags *tag;
06862 while ((tag = &subtags[i++])->type != 0) {
06863 if (tag->id != BSWAP32(id) || tag->type != type) continue;
06864 switch (type) {
06865 default: NOT_REACHED();
06866
06867 case 'T': {
06868 byte langid = buf->ReadByte();
06869 return tag->handler.text(langid, buf->ReadString());
06870 }
06871
06872 case 'B': {
06873 size_t len = buf->ReadWord();
06874 if (buf->Remaining() < len) return false;
06875 return tag->handler.data(len, buf);
06876 }
06877
06878 case 'C': {
06879 if (tag->handler.call_handler) {
06880 return tag->handler.u.branch(buf);
06881 }
06882 return HandleNodes(buf, tag->handler.u.subtags);
06883 }
06884 }
06885 }
06886 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
06887 return SkipUnknownInfo(buf, type);
06888 }
06889
06890 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
06891 {
06892 byte type = buf->ReadByte();
06893 while (type != 0) {
06894 uint32 id = buf->ReadDWord();
06895 if (!HandleNode(type, id, buf, subtags)) return false;
06896 type = buf->ReadByte();
06897 }
06898 return true;
06899 }
06900
06901
06902 static void StaticGRFInfo(ByteReader *buf)
06903 {
06904
06905 HandleNodes(buf, _tags_root);
06906 }
06907
06908
06909 static void GRFDataBlock(ByteReader *buf)
06910 {
06911
06912
06913 if (_grf_data_blocks == 0) {
06914 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
06915 return;
06916 }
06917
06918 uint8 name_len = buf->ReadByte();
06919 const char *name = reinterpret_cast<const char *>(buf->Data());
06920 buf->Skip(name_len);
06921
06922
06923 if (buf->ReadByte() != 0) {
06924 grfmsg(2, "GRFDataBlock: Name not properly terminated");
06925 return;
06926 }
06927
06928 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
06929
06930 _grf_data_blocks--;
06931
06932 switch (_grf_data_type) {
06933 case GDT_SOUND: LoadGRFSound(buf); break;
06934 default: NOT_REACHED();
06935 }
06936 }
06937
06938
06939
06940 static void GRFUnsafe(ByteReader *buf)
06941 {
06942 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06943
06944
06945 _skip_sprites = -1;
06946 }
06947
06948
06949 static void InitializeGRFSpecial()
06950 {
06951 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
06952 | (1 << 0x0D)
06953 | (1 << 0x0E)
06954 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
06955 | (0 << 0x10)
06956 | (1 << 0x12)
06957 | (1 << 0x13)
06958 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
06959 | (1 << 0x1B)
06960 | (1 << 0x1D)
06961 | (1 << 0x1E);
06962
06963 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
06964 | (1 << 0x08)
06965 | (1 << 0x09)
06966 | (0 << 0x0B)
06967 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
06968 | (1 << 0x12)
06969 | (1 << 0x13)
06970 | (1 << 0x14)
06971 | (1 << 0x16)
06972 | (1 << 0x17)
06973 | (1 << 0x18)
06974 | (1 << 0x19)
06975 | (1 << 0x1A)
06976 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
06977 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
06978
06979 _ttdpatch_flags[2] = (1 << 0x01)
06980 | (1 << 0x03)
06981 | (1 << 0x0A)
06982 | (0 << 0x0B)
06983 | (0 << 0x0C)
06984 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
06985 | (1 << 0x0E)
06986 | (1 << 0x0F)
06987 | (0 << 0x10)
06988 | (0 << 0x11)
06989 | (1 << 0x12)
06990 | (1 << 0x13)
06991 | (1 << 0x14)
06992 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
06993 | (1 << 0x16)
06994 | (1 << 0x17)
06995 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
06996 | (1 << 0x19)
06997 | (1 << 0x1A)
06998 | (1 << 0x1B)
06999 | (1 << 0x1C)
07000 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07001 | (1 << 0x1E)
07002 | (0 << 0x1F);
07003
07004 _ttdpatch_flags[3] = (0 << 0x00)
07005 | (1 << 0x01)
07006 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07007 | (1 << 0x03)
07008 | (0 << 0x04)
07009 | (1 << 0x05)
07010 | (1 << 0x06)
07011 | (1 << 0x07)
07012 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07013 | (0 << 0x09)
07014 | (0 << 0x0A)
07015 | (1 << 0x0B)
07016 | (1 << 0x0C)
07017 | (1 << 0x0D)
07018 | (1 << 0x0E)
07019 | (1 << 0x0F)
07020 | (1 << 0x10)
07021 | (1 << 0x11)
07022 | (1 << 0x12)
07023 | (0 << 0x13)
07024 | (1 << 0x14)
07025 | (0 << 0x15)
07026 | (1 << 0x16)
07027 | (1 << 0x17)
07028 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07029 | (1 << 0x1E)
07030 | (1 << 0x1F);
07031 }
07032
07033 static void ResetCustomStations()
07034 {
07035 const GRFFile * const *end = _grf_files.End();
07036 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07037 StationSpec **&stations = (*file)->stations;
07038 if (stations == NULL) continue;
07039 for (uint i = 0; i < MAX_STATIONS; i++) {
07040 if (stations[i] == NULL) continue;
07041 StationSpec *statspec = stations[i];
07042
07043 delete[] statspec->renderdata;
07044
07045
07046 if (!statspec->copied_layouts) {
07047 for (uint l = 0; l < statspec->lengths; l++) {
07048 for (uint p = 0; p < statspec->platforms[l]; p++) {
07049 free(statspec->layouts[l][p]);
07050 }
07051 free(statspec->layouts[l]);
07052 }
07053 free(statspec->layouts);
07054 free(statspec->platforms);
07055 }
07056
07057
07058 free(statspec);
07059 }
07060
07061
07062 free(stations);
07063 stations = NULL;
07064 }
07065 }
07066
07067 static void ResetCustomHouses()
07068 {
07069 const GRFFile * const *end = _grf_files.End();
07070 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07071 HouseSpec **&housespec = (*file)->housespec;
07072 if (housespec == NULL) continue;
07073 for (uint i = 0; i < HOUSE_MAX; i++) {
07074 free(housespec[i]);
07075 }
07076
07077 free(housespec);
07078 housespec = NULL;
07079 }
07080 }
07081
07082 static void ResetCustomAirports()
07083 {
07084 const GRFFile * const *end = _grf_files.End();
07085 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07086 AirportSpec **aslist = (*file)->airportspec;
07087 if (aslist != NULL) {
07088 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07089 AirportSpec *as = aslist[i];
07090
07091 if (as != NULL) {
07092
07093 for (int j = 0; j < as->num_table; j++) {
07094
07095 free((void*)as->table[j]);
07096 }
07097 free((void*)as->table);
07098
07099 free(as);
07100 }
07101 }
07102 free(aslist);
07103 (*file)->airportspec = NULL;
07104 }
07105
07106 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07107 if (airporttilespec != NULL) {
07108 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07109 free(airporttilespec[i]);
07110 }
07111 free(airporttilespec);
07112 airporttilespec = NULL;
07113 }
07114 }
07115 }
07116
07117 static void ResetCustomIndustries()
07118 {
07119 const GRFFile * const *end = _grf_files.End();
07120 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07121 IndustrySpec **&industryspec = (*file)->industryspec;
07122 IndustryTileSpec **&indtspec = (*file)->indtspec;
07123
07124
07125
07126 if (industryspec != NULL) {
07127 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07128 IndustrySpec *ind = industryspec[i];
07129 if (ind == NULL) continue;
07130
07131
07132 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07133 free((void*)ind->random_sounds);
07134 }
07135
07136
07137 CleanIndustryTileTable(ind);
07138
07139 free(ind);
07140 }
07141
07142 free(industryspec);
07143 industryspec = NULL;
07144 }
07145
07146 if (indtspec == NULL) continue;
07147 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07148 free(indtspec[i]);
07149 }
07150
07151 free(indtspec);
07152 indtspec = NULL;
07153 }
07154 }
07155
07156 static void ResetCustomObjects()
07157 {
07158 const GRFFile * const *end = _grf_files.End();
07159 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07160 ObjectSpec **&objectspec = (*file)->objectspec;
07161 if (objectspec == NULL) continue;
07162 for (uint i = 0; i < NUM_OBJECTS; i++) {
07163 free(objectspec[i]);
07164 }
07165
07166 free(objectspec);
07167 objectspec = NULL;
07168 }
07169 }
07170
07171
07172 static void ResetNewGRF()
07173 {
07174 const GRFFile * const *end = _grf_files.End();
07175 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07176 GRFFile *f = *file;
07177 free(f->filename);
07178 free(f->cargo_list);
07179 free(f->railtype_list);
07180 delete [] f->language_map;
07181 free(f);
07182 }
07183
07184 _grf_files.Clear();
07185 _cur_grffile = NULL;
07186 }
07187
07188 static void ResetNewGRFErrors()
07189 {
07190 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07191 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07192 delete c->error;
07193 c->error = NULL;
07194 }
07195 }
07196 }
07197
07202 void ResetNewGRFData()
07203 {
07204 CleanUpStrings();
07205 CleanUpGRFTownNames();
07206
07207
07208 SetupEngines();
07209
07210
07211 ResetBridges();
07212
07213
07214 ResetRailTypes();
07215
07216
07217 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07218
07219
07220 Engine *e;
07221 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07222 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07223 }
07224
07225
07226 memset(&_grm_engines, 0, sizeof(_grm_engines));
07227 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
07228
07229
07230 ResetGenericCallbacks();
07231
07232
07233 ResetPriceBaseMultipliers();
07234
07235
07236 ResetCurrencies();
07237
07238
07239 ResetCustomHouses();
07240 ResetHouses();
07241
07242
07243 ResetCustomIndustries();
07244 ResetIndustries();
07245
07246
07247 ObjectClass::Reset();
07248 ResetCustomObjects();
07249 ResetObjects();
07250
07251
07252 StationClass::Reset();
07253 ResetCustomStations();
07254
07255
07256 AirportClass::Reset();
07257 ResetCustomAirports();
07258 AirportSpec::ResetAirports();
07259 AirportTileSpec::ResetAirportTiles();
07260
07261
07262 memset(_water_feature, 0, sizeof(_water_feature));
07263
07264
07265 ClearSnowLine();
07266
07267
07268 ResetNewGRF();
07269
07270
07271 ResetNewGRFErrors();
07272
07273
07274 SetupCargoForClimate(_settings_game.game_creation.landscape);
07275
07276
07277 _misc_grf_features = 0;
07278
07279 _loaded_newgrf_features.has_2CC = false;
07280 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07281 _loaded_newgrf_features.has_newhouses = false;
07282 _loaded_newgrf_features.has_newindustries = false;
07283 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07284
07285
07286 _grf_id_overrides.clear();
07287
07288 InitializeSoundPool();
07289 _spritegroup_pool.CleanPool();
07290 }
07291
07292 static void BuildCargoTranslationMap()
07293 {
07294 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
07295
07296 for (CargoID c = 0; c < NUM_CARGO; c++) {
07297 const CargoSpec *cs = CargoSpec::Get(c);
07298 if (!cs->IsValid()) continue;
07299
07300 if (_cur_grffile->cargo_max == 0) {
07301
07302 _cur_grffile->cargo_map[c] = cs->bitnum;
07303 } else {
07304
07305 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
07306 if (cs->label == _cur_grffile->cargo_list[i]) {
07307 _cur_grffile->cargo_map[c] = i;
07308 break;
07309 }
07310 }
07311 }
07312 }
07313 }
07314
07315 static void InitNewGRFFile(const GRFConfig *config)
07316 {
07317 GRFFile *newfile = GetFileByFilename(config->filename);
07318 if (newfile != NULL) {
07319
07320 _cur_grffile = newfile;
07321 return;
07322 }
07323
07324 newfile = CallocT<GRFFile>(1);
07325
07326 newfile->filename = strdup(config->filename);
07327 newfile->grfid = config->ident.grfid;
07328
07329
07330 newfile->traininfo_vehicle_pitch = 0;
07331 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
07332
07333
07334 for (Price i = PR_BEGIN; i < PR_END; i++) {
07335 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
07336 }
07337
07338
07339 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
07340 newfile->railtype_map[0] = RAILTYPE_RAIL;
07341 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
07342 newfile->railtype_map[2] = RAILTYPE_MONO;
07343 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
07344
07345
07346
07347 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
07348 memset(newfile->param, 0, sizeof(newfile->param));
07349
07350 assert(config->num_params <= lengthof(config->param));
07351 newfile->param_end = config->num_params;
07352 if (newfile->param_end > 0) {
07353 MemCpyT(newfile->param, config->param, newfile->param_end);
07354 }
07355
07356 *_grf_files.Append() = _cur_grffile = newfile;
07357 }
07358
07359
07364 static const CargoLabel _default_refitmasks_rail[] = {
07365 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
07366 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
07367 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07368 'PLST', 'FZDR',
07369 0 };
07370
07371 static const CargoLabel _default_refitmasks_road[] = {
07372 0 };
07373
07374 static const CargoLabel _default_refitmasks_ships[] = {
07375 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
07376 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
07377 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07378 'PLST', 'FZDR',
07379 0 };
07380
07381 static const CargoLabel _default_refitmasks_aircraft[] = {
07382 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
07383 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
07384 0 };
07385
07386 static const CargoLabel * const _default_refitmasks[] = {
07387 _default_refitmasks_rail,
07388 _default_refitmasks_road,
07389 _default_refitmasks_ships,
07390 _default_refitmasks_aircraft,
07391 };
07392
07393
07397 static void CalculateRefitMasks()
07398 {
07399 Engine *e;
07400
07401 FOR_ALL_ENGINES(e) {
07402 EngineID engine = e->index;
07403 EngineInfo *ei = &e->info;
07404 uint32 mask = 0;
07405 uint32 not_mask = 0;
07406 uint32 xor_mask = 0;
07407
07408
07409 if (_gted[engine].refitmask_valid) {
07410 if (ei->refit_mask != 0) {
07411 const GRFFile *file = _gted[engine].refitmask_grf;
07412 if (file == NULL) file = e->grf_prop.grffile;
07413 if (file != NULL && file->cargo_max != 0) {
07414
07415 uint num_cargo = min(32, file->cargo_max);
07416 for (uint i = 0; i < num_cargo; i++) {
07417 if (!HasBit(ei->refit_mask, i)) continue;
07418
07419 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
07420 if (c == CT_INVALID) continue;
07421
07422 SetBit(xor_mask, c);
07423 }
07424 } else {
07425
07426 const CargoSpec *cs;
07427 FOR_ALL_CARGOSPECS(cs) {
07428 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
07429 }
07430 }
07431 }
07432
07433 if (_gted[engine].cargo_allowed != 0) {
07434
07435 const CargoSpec *cs;
07436 FOR_ALL_CARGOSPECS(cs) {
07437 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
07438 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
07439 }
07440 }
07441 } else {
07442
07443 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
07444 const CargoLabel *cl = _default_refitmasks[e->type];
07445 for (uint i = 0;; i++) {
07446 if (cl[i] == 0) break;
07447
07448 CargoID cargo = GetCargoIDByLabel(cl[i]);
07449 if (cargo == CT_INVALID) continue;
07450
07451 SetBit(xor_mask, cargo);
07452 }
07453 }
07454 }
07455
07456 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
07457
07458
07459
07460 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
07461 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
07462
07463
07464 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
07465 }
07466 }
07467
07469 static void FinaliseEngineArray()
07470 {
07471 Engine *e;
07472
07473 FOR_ALL_ENGINES(e) {
07474 if (e->grf_prop.grffile == NULL) {
07475 const EngineIDMapping &eid = _engine_mngr[e->index];
07476 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
07477 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
07478 }
07479 }
07480
07481
07482
07483
07484 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->grf_prop.grffile != NULL && is_custom_sprite(e->u.rail.image_index)) {
07485 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
07486 }
07487
07488
07489 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
07490 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
07491 SetBit(_loaded_newgrf_features.used_liveries, ls);
07492
07493
07494 if (e->type == VEH_TRAIN) {
07495 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
07496 switch (ls) {
07497 case LS_STEAM:
07498 case LS_DIESEL:
07499 case LS_ELECTRIC:
07500 case LS_MONORAIL:
07501 case LS_MAGLEV:
07502 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
07503 break;
07504
07505 case LS_DMU:
07506 case LS_EMU:
07507 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
07508 break;
07509
07510 default: NOT_REACHED();
07511 }
07512 }
07513 }
07514 }
07515 }
07516
07518 static void FinaliseCargoArray()
07519 {
07520 for (CargoID c = 0; c < NUM_CARGO; c++) {
07521 CargoSpec *cs = CargoSpec::Get(c);
07522 if (!cs->IsValid()) {
07523 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
07524 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
07525 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
07526 }
07527 }
07528 }
07529
07541 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
07542 {
07543 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
07544 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
07545 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
07546 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
07547 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
07548 hs->enabled = false;
07549 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
07550 return false;
07551 }
07552
07553
07554
07555
07556 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
07557 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
07558 hs->enabled = false;
07559 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
07560 return false;
07561 }
07562
07563
07564
07565 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
07566 hs->enabled = false;
07567 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
07568 return false;
07569 }
07570
07571
07572 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
07573 hs->enabled = false;
07574 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
07575 return false;
07576 }
07577
07578 return true;
07579 }
07580
07587 static void EnsureEarlyHouse(HouseZones bitmask)
07588 {
07589 Year min_year = MAX_YEAR;
07590
07591 for (int i = 0; i < HOUSE_MAX; i++) {
07592 HouseSpec *hs = HouseSpec::Get(i);
07593 if (hs == NULL || !hs->enabled) continue;
07594 if ((hs->building_availability & bitmask) != bitmask) continue;
07595 if (hs->min_year < min_year) min_year = hs->min_year;
07596 }
07597
07598 if (min_year == 0) return;
07599
07600 for (int i = 0; i < HOUSE_MAX; i++) {
07601 HouseSpec *hs = HouseSpec::Get(i);
07602 if (hs == NULL || !hs->enabled) continue;
07603 if ((hs->building_availability & bitmask) != bitmask) continue;
07604 if (hs->min_year == min_year) hs->min_year = 0;
07605 }
07606 }
07607
07614 static void FinaliseHouseArray()
07615 {
07616
07617
07618
07619
07620
07621
07622
07623
07624
07625 const GRFFile * const *end = _grf_files.End();
07626 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07627 HouseSpec **&housespec = (*file)->housespec;
07628 if (housespec == NULL) continue;
07629
07630 for (int i = 0; i < HOUSE_MAX; i++) {
07631 HouseSpec *hs = housespec[i];
07632
07633 if (hs == NULL) continue;
07634
07635 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
07636 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
07637 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
07638
07639 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
07640
07641 _house_mngr.SetEntitySpec(hs);
07642 }
07643 }
07644
07645 for (int i = 0; i < HOUSE_MAX; i++) {
07646 HouseSpec *hs = HouseSpec::Get(i);
07647 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
07648 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
07649 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
07650
07651
07652
07653 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
07654
07655
07656
07657
07658
07659
07660
07661 hs->building_flags = TILE_NO_FLAG;
07662 }
07663 }
07664
07665 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
07666 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
07667 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
07668 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
07669 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
07670 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
07671
07672 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
07673 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
07674 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
07675 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
07676 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
07677 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
07678 }
07679 }
07680
07686 static void FinaliseIndustriesArray()
07687 {
07688 const GRFFile * const *end = _grf_files.End();
07689 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07690 IndustrySpec **&industryspec = (*file)->industryspec;
07691 IndustryTileSpec **&indtspec = (*file)->indtspec;
07692 if (industryspec != NULL) {
07693 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
07694 IndustrySpec *indsp = industryspec[i];
07695
07696 if (indsp != NULL && indsp->enabled) {
07697 StringID strid;
07698
07699
07700
07701 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
07702 if (strid != STR_UNDEFINED) indsp->name = strid;
07703
07704 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
07705 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
07706
07707 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
07708 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
07709
07710 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
07711 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
07712
07713 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
07714 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
07715
07716 if (indsp->station_name != STR_NULL) {
07717
07718
07719 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
07720 if (strid != STR_UNDEFINED) indsp->station_name = strid;
07721 }
07722
07723 _industry_mngr.SetEntitySpec(indsp);
07724 _loaded_newgrf_features.has_newindustries = true;
07725 }
07726 }
07727 }
07728
07729 if (indtspec != NULL) {
07730 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
07731 IndustryTileSpec *indtsp = indtspec[i];
07732 if (indtsp != NULL) {
07733 _industile_mngr.SetEntitySpec(indtsp);
07734 }
07735 }
07736 }
07737 }
07738
07739 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
07740 IndustrySpec *indsp = &_industry_specs[j];
07741 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
07742 for (uint i = 0; i < 3; i++) {
07743 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
07744 }
07745 }
07746 if (!indsp->enabled) {
07747 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
07748 }
07749 }
07750 }
07751
07757 static void FinaliseObjectsArray()
07758 {
07759 const GRFFile * const *end = _grf_files.End();
07760 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07761 ObjectSpec **&objectspec = (*file)->objectspec;
07762 if (objectspec != NULL) {
07763 for (int i = 0; i < NUM_OBJECTS; i++) {
07764 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
07765 _object_mngr.SetEntitySpec(objectspec[i]);
07766 }
07767 }
07768 }
07769 }
07770 }
07771
07777 static void FinaliseAirportsArray()
07778 {
07779 const GRFFile * const *end = _grf_files.End();
07780 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07781 AirportSpec **&airportspec = (*file)->airportspec;
07782 if (airportspec != NULL) {
07783 for (int i = 0; i < NUM_AIRPORTS; i++) {
07784 if (airportspec[i] != NULL && airportspec[i]->enabled) {
07785 _airport_mngr.SetEntitySpec(airportspec[i]);
07786 }
07787 }
07788 }
07789
07790 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07791 if (airporttilespec != NULL) {
07792 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07793 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
07794 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
07795 }
07796 }
07797 }
07798 }
07799 }
07800
07801
07802
07803
07804
07805
07806
07807 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
07808 {
07809
07810
07811
07812
07813
07814
07815
07816
07817
07818
07819
07820
07821 static const SpecialSpriteHandler handlers[][GLS_END] = {
07822 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
07823 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
07824 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
07825 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
07826 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
07827 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
07828 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
07829 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
07830 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
07831 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
07832 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
07833 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
07834 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
07835 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
07836 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
07837 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
07838 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
07839 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
07840 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
07841 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
07842 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
07843 };
07844
07845 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line);
07846
07847 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
07848 if (it == _grf_line_to_action6_sprite_override.end()) {
07849
07850
07851 FioReadBlock(buf, num);
07852 } else {
07853
07854 buf = _grf_line_to_action6_sprite_override[location];
07855 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
07856
07857
07858 FioSeekTo(num, SEEK_CUR);
07859 }
07860
07861 ByteReader br(buf, buf + num);
07862 ByteReader *bufp = &br;
07863
07864 try {
07865 byte action = bufp->ReadByte();
07866
07867 if (action == 0xFF) {
07868 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
07869 GRFDataBlock(bufp);
07870 } else if (action == 0xFE) {
07871 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
07872 GRFImportBlock(bufp);
07873 } else if (action >= lengthof(handlers)) {
07874 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
07875 } else if (handlers[action][stage] == NULL) {
07876 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
07877 } else {
07878 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
07879 handlers[action][stage](bufp);
07880 }
07881 } catch (...) {
07882 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
07883 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
07884 }
07885 }
07886
07887
07888 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
07889 {
07890 const char *filename = config->filename;
07891 uint16 num;
07892
07893
07894
07895
07896
07897
07898
07899
07900
07901
07902 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
07903 _cur_grffile = GetFileByFilename(filename);
07904 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
07905 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
07906 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
07907 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
07908 }
07909
07910 if (file_index > LAST_GRF_SLOT) {
07911 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
07912 config->status = GCS_DISABLED;
07913 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
07914 return;
07915 }
07916
07917 FioOpenFile(file_index, filename);
07918 _file_index = file_index;
07919 _palette_remap_grf[_file_index] = (config->palette & GRFP_USE_MASK);
07920
07921 _cur_grfconfig = config;
07922
07923 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
07924
07925
07926
07927
07928 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
07929 FioReadDword();
07930 } else {
07931 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
07932 return;
07933 }
07934
07935 _skip_sprites = 0;
07936 _nfo_line = 0;
07937
07938 ReusableBuffer<byte> buf;
07939
07940 while ((num = FioReadWord()) != 0) {
07941 byte type = FioReadByte();
07942 _nfo_line++;
07943
07944 if (type == 0xFF) {
07945 if (_skip_sprites == 0) {
07946 DecodeSpecialSprite(buf.Allocate(num), num, stage);
07947
07948
07949 if (_skip_sprites == -1) break;
07950
07951 continue;
07952 } else {
07953 FioSkipBytes(num);
07954 }
07955 } else {
07956 if (_skip_sprites == 0) {
07957 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
07958 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
07959 break;
07960 }
07961
07962 FioSkipBytes(7);
07963 SkipSpriteData(type, num - 8);
07964 }
07965
07966 if (_skip_sprites > 0) _skip_sprites--;
07967 }
07968 }
07969
07977 static void ActivateOldShore()
07978 {
07979
07980
07981 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
07982
07983 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
07984 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
07985 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
07986 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
07987 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
07988 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
07989 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
07990 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
07991 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
07992 }
07993
07994 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
07995 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
07996 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
07997 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
07998 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
07999 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08000 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08001 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08002 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08003
08004
08005
08006 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08007 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08008 }
08009 }
08010
08014 static void FinalisePriceBaseMultipliers()
08015 {
08016 extern const PriceBaseSpec _price_base_specs[];
08018 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08019
08020
08021 int num_grfs = _grf_files.Length();
08022 int *grf_overrides = AllocaM(int, num_grfs);
08023 for (int i = 0; i < num_grfs; i++) {
08024 grf_overrides[i] = -1;
08025
08026 GRFFile *source = _grf_files[i];
08027 uint32 override = _grf_id_overrides[source->grfid];
08028 if (override == 0) continue;
08029
08030 GRFFile *dest = GetFileByGRFID(override);
08031 if (dest == NULL) continue;
08032
08033 grf_overrides[i] = _grf_files.FindIndex(dest);
08034 assert(grf_overrides[i] >= 0);
08035 }
08036
08037
08038 for (int i = 0; i < num_grfs; i++) {
08039 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08040 GRFFile *source = _grf_files[i];
08041 GRFFile *dest = _grf_files[grf_overrides[i]];
08042
08043 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08044 source->grf_features |= features;
08045 dest->grf_features |= features;
08046
08047 for (Price p = PR_BEGIN; p < PR_END; p++) {
08048
08049 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08050 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08051 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08052 }
08053 }
08054
08055
08056 for (int i = num_grfs - 1; i >= 0; i--) {
08057 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08058 GRFFile *source = _grf_files[i];
08059 GRFFile *dest = _grf_files[grf_overrides[i]];
08060
08061 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08062 source->grf_features |= features;
08063 dest->grf_features |= features;
08064
08065 for (Price p = PR_BEGIN; p < PR_END; p++) {
08066
08067 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08068 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08069 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08070 }
08071 }
08072
08073
08074 for (int i = 0; i < num_grfs; i++) {
08075 if (grf_overrides[i] < 0) continue;
08076 GRFFile *source = _grf_files[i];
08077 GRFFile *dest = _grf_files[grf_overrides[i]];
08078
08079 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08080 source->grf_features |= features;
08081 dest->grf_features |= features;
08082
08083 for (Price p = PR_BEGIN; p < PR_END; p++) {
08084 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08085 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08086 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08087 }
08088 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08089 }
08090 }
08091
08092
08093 const GRFFile * const *end = _grf_files.End();
08094 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08095 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08096 for (Price p = PR_BEGIN; p < PR_END; p++) {
08097 Price fallback_price = _price_base_specs[p].fallback_price;
08098 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08099
08100
08101 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08102 }
08103 }
08104 }
08105
08106
08107 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08108 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08109 for (Price p = PR_BEGIN; p < PR_END; p++) {
08110 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08111
08112 price_base_multipliers[p] = 0;
08113 } else {
08114 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08115
08116
08117 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08118 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08119 price_base_multipliers[p] = 0;
08120 } else {
08121 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08122 }
08123 }
08124 }
08125 }
08126 }
08127
08128 void InitDepotWindowBlockSizes();
08129
08130 extern void InitGRFTownGeneratorNames();
08131
08132 static void AfterLoadGRFs()
08133 {
08134 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08135 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08136 }
08137 _string_to_grf_mapping.clear();
08138
08139
08140 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08141 free((*it).second);
08142 }
08143 _grf_line_to_action6_sprite_override.clear();
08144
08145
08146 FinaliseCargoArray();
08147
08148
08149 CalculateRefitMasks();
08150
08151
08152 FinaliseEngineArray();
08153
08154
08155 InitDepotWindowBlockSizes();
08156
08157
08158 FinaliseHouseArray();
08159
08160
08161 FinaliseIndustriesArray();
08162
08163
08164 FinaliseObjectsArray();
08165
08166 InitializeSortedCargoSpecs();
08167
08168
08169 SortIndustryTypes();
08170
08171
08172 BuildIndustriesLegend();
08173
08174
08175 BuildLinkStatsLegend();
08176
08177
08178 FinaliseAirportsArray();
08179 BindAirportSpecs();
08180
08181
08182 InitGRFTownGeneratorNames();
08183
08184
08185 CommitVehicleListOrderChanges();
08186
08187
08188 ActivateOldShore();
08189
08190
08191 InitRailTypes();
08192
08193 Engine *e;
08194 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
08195 if (_gted[e->index].rv_max_speed != 0) {
08196
08197 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
08198 }
08199 }
08200
08201 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
08202 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
08203 if (railtype == INVALID_RAILTYPE) {
08204
08205 e->info.climates = 0;
08206 } else {
08207 e->u.rail.railtype = railtype;
08208 }
08209 }
08210
08211 SetYearEngineAgingStops();
08212
08213 FinalisePriceBaseMultipliers();
08214
08215
08216 free(_gted);
08217 _grm_sprites.clear();
08218 }
08219
08220 void LoadNewGRF(uint load_index, uint file_index)
08221 {
08222
08223
08224
08225
08226 Date date = _date;
08227 Year year = _cur_year;
08228 DateFract date_fract = _date_fract;
08229 uint16 tick_counter = _tick_counter;
08230 byte display_opt = _display_opt;
08231
08232 if (_networking) {
08233 _cur_year = _settings_game.game_creation.starting_year;
08234 _date = ConvertYMDToDate(_cur_year, 0, 1);
08235 _date_fract = 0;
08236 _tick_counter = 0;
08237 _display_opt = 0;
08238 }
08239
08240 InitializeGRFSpecial();
08241
08242 ResetNewGRFData();
08243
08244
08245
08246
08247
08248
08249
08250
08251 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08252 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
08253 }
08254
08255 _cur_spriteid = load_index;
08256
08257
08258
08259
08260 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
08261
08262
08263 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08264 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
08265 }
08266
08267 uint slot = file_index;
08268
08269 _cur_stage = stage;
08270 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08271 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
08272 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
08273
08274 if (!FioCheckFileExists(c->filename)) {
08275 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
08276 c->status = GCS_NOT_FOUND;
08277 continue;
08278 }
08279
08280 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
08281 LoadNewGRFFile(c, slot++, stage);
08282 if (stage == GLS_RESERVE) {
08283 SetBit(c->flags, GCF_RESERVED);
08284 } else if (stage == GLS_ACTIVATION) {
08285 ClrBit(c->flags, GCF_RESERVED);
08286 assert(GetFileByGRFID(c->ident.grfid) == _cur_grffile);
08287 ClearTemporaryNewGRFData(_cur_grffile);
08288 BuildCargoTranslationMap();
08289 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
08290 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
08291
08292 ClearTemporaryNewGRFData(_cur_grffile);
08293 }
08294 }
08295 }
08296
08297
08298 AfterLoadGRFs();
08299
08300
08301 _cur_year = year;
08302 _date = date;
08303 _date_fract = date_fract;
08304 _tick_counter = tick_counter;
08305 _display_opt = display_opt;
08306 }
08307
08308 bool HasGrfMiscBit(GrfMiscBit bit)
08309 {
08310 return HasBit(_misc_grf_features, bit);
08311 }