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