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