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() * 128) / 10;
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 default:
06375 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
06376 return 0;
06377 }
06378 }
06379
06380
06381 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
06382 {
06383 uint start = 0;
06384 uint size = 0;
06385
06386 if (op == 6) {
06387
06388 return grm[_cur.grffile->GetParam(target)];
06389 }
06390
06391
06392 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
06393
06394 for (uint i = start; i < num_ids; i++) {
06395 if (grm[i] == 0) {
06396 size++;
06397 } else {
06398 if (op == 2 || op == 3) break;
06399 start = i + 1;
06400 size = 0;
06401 }
06402
06403 if (size == count) break;
06404 }
06405
06406 if (size == count) {
06407
06408 if (op == 0 || op == 3) {
06409 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
06410 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
06411 }
06412 return start;
06413 }
06414
06415
06416 if (op != 4 && op != 5) {
06417
06418 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
06419 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06420 return UINT_MAX;
06421 }
06422
06423 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
06424 return UINT_MAX;
06425 }
06426
06427
06429 static void ParamSet(ByteReader *buf)
06430 {
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445
06446
06447
06448
06449
06450
06451
06452
06453 uint8 target = buf->ReadByte();
06454 uint8 oper = buf->ReadByte();
06455 uint32 src1 = buf->ReadByte();
06456 uint32 src2 = buf->ReadByte();
06457
06458 uint32 data = 0;
06459 if (buf->Remaining() >= 4) data = buf->ReadDWord();
06460
06461
06462
06463
06464
06465
06466
06467 if (HasBit(oper, 7)) {
06468 if (target < 0x80 && target < _cur.grffile->param_end) {
06469 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
06470 return;
06471 }
06472
06473 oper = GB(oper, 0, 7);
06474 }
06475
06476 if (src2 == 0xFE) {
06477 if (GB(data, 0, 8) == 0xFF) {
06478 if (data == 0x0000FFFF) {
06479
06480 src1 = GetPatchVariable(src1);
06481 } else {
06482
06483 uint8 op = src1;
06484 uint8 feature = GB(data, 8, 8);
06485 uint16 count = GB(data, 16, 16);
06486
06487 if (_cur.stage == GLS_RESERVE) {
06488 if (feature == 0x08) {
06489
06490 if (op == 0) {
06491
06492 if (_cur.spriteid + count >= 16384) {
06493 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
06494 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06495 return;
06496 }
06497
06498
06499 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
06500 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
06501 _cur.spriteid += count;
06502 }
06503 }
06504
06505 src1 = 0;
06506 } else if (_cur.stage == GLS_ACTIVATION) {
06507 switch (feature) {
06508 case 0x00:
06509 case 0x01:
06510 case 0x02:
06511 case 0x03:
06512 if (!_settings_game.vehicle.dynamic_engines) {
06513 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
06514 if (_cur.skip_sprites == -1) return;
06515 } else {
06516
06517 switch (op) {
06518 case 2:
06519 case 3:
06520 src1 = _cur.grffile->GetParam(target);
06521 break;
06522
06523 default:
06524 src1 = 0;
06525 break;
06526 }
06527 }
06528 break;
06529
06530 case 0x08:
06531 switch (op) {
06532 case 0:
06533
06534 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
06535 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
06536 break;
06537
06538 case 1:
06539 src1 = _cur.spriteid;
06540 break;
06541
06542 default:
06543 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
06544 return;
06545 }
06546 break;
06547
06548 case 0x0B:
06549
06550 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
06551 if (_cur.skip_sprites == -1) return;
06552 break;
06553
06554 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
06555 }
06556 } else {
06557
06558 src1 = 0;
06559 }
06560 }
06561 } else {
06562
06563 const GRFFile *file = GetFileByGRFID(data);
06564 GRFConfig *c = GetGRFConfig(data);
06565 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
06566
06567 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
06568 src1 = 0;
06569 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
06570 src1 = 0;
06571 } else if (src1 == 0xFE) {
06572 src1 = c->version;
06573 } else {
06574 src1 = file->GetParam(src1);
06575 }
06576 }
06577 } else {
06578
06579
06580
06581
06582
06583 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
06584 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
06585 }
06586
06587
06588
06589
06590
06591
06592
06593 uint32 res;
06594 switch (oper) {
06595 case 0x00:
06596 res = src1;
06597 break;
06598
06599 case 0x01:
06600 res = src1 + src2;
06601 break;
06602
06603 case 0x02:
06604 res = src1 - src2;
06605 break;
06606
06607 case 0x03:
06608 res = src1 * src2;
06609 break;
06610
06611 case 0x04:
06612 res = (int32)src1 * (int32)src2;
06613 break;
06614
06615 case 0x05:
06616 if ((int32)src2 < 0) {
06617 res = src1 >> -(int32)src2;
06618 } else {
06619 res = src1 << src2;
06620 }
06621 break;
06622
06623 case 0x06:
06624 if ((int32)src2 < 0) {
06625 res = (int32)src1 >> -(int32)src2;
06626 } else {
06627 res = (int32)src1 << src2;
06628 }
06629 break;
06630
06631 case 0x07:
06632 res = src1 & src2;
06633 break;
06634
06635 case 0x08:
06636 res = src1 | src2;
06637 break;
06638
06639 case 0x09:
06640 if (src2 == 0) {
06641 res = src1;
06642 } else {
06643 res = src1 / src2;
06644 }
06645 break;
06646
06647 case 0x0A:
06648 if (src2 == 0) {
06649 res = src1;
06650 } else {
06651 res = (int32)src1 / (int32)src2;
06652 }
06653 break;
06654
06655 case 0x0B:
06656 if (src2 == 0) {
06657 res = src1;
06658 } else {
06659 res = src1 % src2;
06660 }
06661 break;
06662
06663 case 0x0C:
06664 if (src2 == 0) {
06665 res = src1;
06666 } else {
06667 res = (int32)src1 % (int32)src2;
06668 }
06669 break;
06670
06671 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06672 }
06673
06674 switch (target) {
06675 case 0x8E:
06676 _cur.grffile->traininfo_vehicle_pitch = res;
06677 break;
06678
06679 case 0x8F: {
06680 extern RailtypeInfo _railtypes[RAILTYPE_END];
06681 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06682 if (_settings_game.vehicle.disable_elrails) {
06683 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06684 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06685 } else {
06686 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06687 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06688 }
06689 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06690 break;
06691 }
06692
06693
06694 case 0x93:
06695 case 0x94:
06696 case 0x95:
06697 case 0x96:
06698 case 0x97:
06699 case 0x99:
06700 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06701 break;
06702
06703 case 0x9E:
06704
06705 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06706
06707 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
06708
06709 _misc_grf_features = res;
06710 break;
06711
06712 case 0x9F:
06713 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06714 break;
06715
06716 default:
06717 if (target < 0x80) {
06718 _cur.grffile->param[target] = res;
06719
06720 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
06721 } else {
06722 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06723 }
06724 break;
06725 }
06726 }
06727
06728
06729 static void SafeGRFInhibit(ByteReader *buf)
06730 {
06731
06732
06733
06734
06735
06736 uint8 num = buf->ReadByte();
06737
06738 for (uint i = 0; i < num; i++) {
06739 uint32 grfid = buf->ReadDWord();
06740
06741
06742 if (grfid != _cur.grfconfig->ident.grfid) {
06743 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06744
06745
06746 _cur.skip_sprites = -1;
06747
06748 return;
06749 }
06750 }
06751 }
06752
06753
06754 static void GRFInhibit(ByteReader *buf)
06755 {
06756
06757
06758
06759
06760
06761 uint8 num = buf->ReadByte();
06762
06763 for (uint i = 0; i < num; i++) {
06764 uint32 grfid = buf->ReadDWord();
06765 GRFConfig *file = GetGRFConfig(grfid);
06766
06767
06768 if (file != NULL && file != _cur.grfconfig) {
06769 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06770 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06771 error->data = strdup(_cur.grfconfig->GetName());
06772 }
06773 }
06774 }
06775
06777 static void FeatureTownName(ByteReader *buf)
06778 {
06779
06780
06781
06782
06783
06784
06785
06786 uint32 grfid = _cur.grffile->grfid;
06787
06788 GRFTownName *townname = AddGRFTownName(grfid);
06789
06790 byte id = buf->ReadByte();
06791 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06792
06793 if (HasBit(id, 7)) {
06794
06795 ClrBit(id, 7);
06796 bool new_scheme = _cur.grffile->grf_version >= 7;
06797
06798 byte lang = buf->ReadByte();
06799
06800 byte nb_gen = townname->nb_gen;
06801 do {
06802 ClrBit(lang, 7);
06803
06804 const char *name = buf->ReadString();
06805
06806 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06807 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06808 free(lang_name);
06809
06810 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06811
06812 lang = buf->ReadByte();
06813 } while (lang != 0);
06814 townname->id[nb_gen] = id;
06815 townname->nb_gen++;
06816 }
06817
06818 byte nb = buf->ReadByte();
06819 grfmsg(6, "FeatureTownName: %u parts", nb);
06820
06821 townname->nbparts[id] = nb;
06822 townname->partlist[id] = CallocT<NamePartList>(nb);
06823
06824 for (int i = 0; i < nb; i++) {
06825 byte nbtext = buf->ReadByte();
06826 townname->partlist[id][i].bitstart = buf->ReadByte();
06827 townname->partlist[id][i].bitcount = buf->ReadByte();
06828 townname->partlist[id][i].maxprob = 0;
06829 townname->partlist[id][i].partcount = nbtext;
06830 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06831 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);
06832
06833 for (int j = 0; j < nbtext; j++) {
06834 byte prob = buf->ReadByte();
06835
06836 if (HasBit(prob, 7)) {
06837 byte ref_id = buf->ReadByte();
06838
06839 if (townname->nbparts[ref_id] == 0) {
06840 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06841 DelGRFTownName(grfid);
06842 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06843 return;
06844 }
06845
06846 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06847 townname->partlist[id][i].parts[j].data.id = ref_id;
06848 } else {
06849 const char *text = buf->ReadString();
06850 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06851 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06852 }
06853 townname->partlist[id][i].parts[j].prob = prob;
06854 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06855 }
06856 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06857 }
06858 }
06859
06861 static void DefineGotoLabel(ByteReader *buf)
06862 {
06863
06864
06865
06866
06867
06868 byte nfo_label = buf->ReadByte();
06869
06870 GRFLabel *label = MallocT<GRFLabel>(1);
06871 label->label = nfo_label;
06872 label->nfo_line = _cur.nfo_line;
06873 label->pos = FioGetPos();
06874 label->next = NULL;
06875
06876
06877 if (_cur.grffile->label == NULL) {
06878 _cur.grffile->label = label;
06879 } else {
06880
06881 GRFLabel *l;
06882 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
06883 l->next = label;
06884 }
06885
06886 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06887 }
06888
06893 static void ImportGRFSound(SoundEntry *sound)
06894 {
06895 const GRFFile *file;
06896 uint32 grfid = FioReadDword();
06897 SoundID sound_id = FioReadWord();
06898
06899 file = GetFileByGRFID(grfid);
06900 if (file == NULL || file->sound_offset == 0) {
06901 grfmsg(1, "ImportGRFSound: Source file not available");
06902 return;
06903 }
06904
06905 if (sound_id >= file->num_sounds) {
06906 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06907 return;
06908 }
06909
06910 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06911
06912 *sound = *GetSound(file->sound_offset + sound_id);
06913
06914
06915 sound->volume = 128;
06916 sound->priority = 0;
06917 }
06918
06924 static void LoadGRFSound(size_t offs, SoundEntry *sound)
06925 {
06926
06927 sound->volume = 0x80;
06928 sound->priority = 0;
06929
06930 if (offs != SIZE_MAX) {
06931
06932 sound->file_slot = _cur.file_index;
06933 sound->file_offset = offs;
06934 sound->grf_container_ver = _cur.grf_container_ver;
06935 }
06936 }
06937
06938
06939 static void GRFSound(ByteReader *buf)
06940 {
06941
06942
06943
06944
06945 uint16 num = buf->ReadWord();
06946 if (num == 0) return;
06947
06948 SoundEntry *sound;
06949 if (_cur.grffile->sound_offset == 0) {
06950 _cur.grffile->sound_offset = GetNumSounds();
06951 _cur.grffile->num_sounds = num;
06952 sound = AllocateSound(num);
06953 } else {
06954 sound = GetSound(_cur.grffile->sound_offset);
06955 }
06956
06957 for (int i = 0; i < num; i++) {
06958 _cur.nfo_line++;
06959
06960
06961
06962 bool invalid = i >= _cur.grffile->num_sounds;
06963
06964 size_t offs = FioGetPos();
06965
06966 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
06967 byte type = FioReadByte();
06968
06969 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
06970
06971 if (invalid) {
06972 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06973 FioSkipBytes(len);
06974 } else if (len != 4) {
06975 grfmsg(1, "GRFSound: Invalid sprite section import");
06976 FioSkipBytes(len);
06977 } else {
06978 uint32 id = FioReadDword();
06979 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
06980 }
06981 continue;
06982 }
06983
06984 if (type != 0xFF) {
06985 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
06986 FioSkipBytes(7);
06987 SkipSpriteData(type, len - 8);
06988 continue;
06989 }
06990
06991 if (invalid) {
06992 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06993 FioSkipBytes(len);
06994 }
06995
06996 byte action = FioReadByte();
06997 switch (action) {
06998 case 0xFF:
06999
07000 if (_cur.stage == GLS_INIT) {
07001 if (_cur.grf_container_ver >= 2) {
07002 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
07003 } else {
07004 LoadGRFSound(offs, sound + i);
07005 }
07006 }
07007 FioSkipBytes(len - 1);
07008 break;
07009
07010 case 0xFE:
07011 if (_cur.stage == GLS_ACTIVATION) {
07012
07013
07014 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
07015 ImportGRFSound(sound + i);
07016 } else {
07017 FioSkipBytes(len - 1);
07018 }
07019 break;
07020
07021 default:
07022 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
07023 FioSkipBytes(len - 1);
07024 break;
07025 }
07026 }
07027 }
07028
07029
07030 static void SkipAct11(ByteReader *buf)
07031 {
07032
07033
07034
07035
07036 _cur.skip_sprites = buf->ReadWord();
07037
07038 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
07039 }
07040
07042 static void LoadFontGlyph(ByteReader *buf)
07043 {
07044
07045
07046
07047
07048
07049
07050
07051 uint8 num_def = buf->ReadByte();
07052
07053 for (uint i = 0; i < num_def; i++) {
07054 FontSize size = (FontSize)buf->ReadByte();
07055 uint8 num_char = buf->ReadByte();
07056 uint16 base_char = buf->ReadWord();
07057
07058 if (size >= FS_END) {
07059 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
07060 }
07061
07062 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
07063
07064 for (uint c = 0; c < num_char; c++) {
07065 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
07066 _cur.nfo_line++;
07067 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
07068 }
07069 }
07070 }
07071
07073 static void SkipAct12(ByteReader *buf)
07074 {
07075
07076
07077
07078
07079
07080
07081
07082 uint8 num_def = buf->ReadByte();
07083
07084 for (uint i = 0; i < num_def; i++) {
07085
07086 buf->ReadByte();
07087
07088
07089 _cur.skip_sprites += buf->ReadByte();
07090
07091
07092 buf->ReadWord();
07093 }
07094
07095 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
07096 }
07097
07099 static void TranslateGRFStrings(ByteReader *buf)
07100 {
07101
07102
07103
07104
07105
07106
07107
07108 uint32 grfid = buf->ReadDWord();
07109 const GRFConfig *c = GetGRFConfig(grfid);
07110 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
07111 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
07112 return;
07113 }
07114
07115 if (c->status == GCS_INITIALISED) {
07116
07117
07118 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
07119
07120 char tmp[256];
07121 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
07122 error->data = strdup(tmp);
07123
07124 return;
07125 }
07126
07127
07128
07129
07130
07131
07132 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
07133 byte num_strings = buf->ReadByte();
07134 uint16 first_id = buf->ReadWord();
07135
07136 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
07137 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
07138 return;
07139 }
07140
07141 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
07142 const char *string = buf->ReadString();
07143
07144 if (StrEmpty(string)) {
07145 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
07146 continue;
07147 }
07148
07149 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
07150 }
07151 }
07152
07154 static bool ChangeGRFName(byte langid, const char *str)
07155 {
07156 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
07157 return true;
07158 }
07159
07161 static bool ChangeGRFDescription(byte langid, const char *str)
07162 {
07163 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
07164 return true;
07165 }
07166
07168 static bool ChangeGRFURL(byte langid, const char *str)
07169 {
07170 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
07171 return true;
07172 }
07173
07175 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
07176 {
07177 if (len != 1) {
07178 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
07179 buf->Skip(len);
07180 } else {
07181 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
07182 }
07183 return true;
07184 }
07185
07187 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
07188 {
07189 if (len != 1) {
07190 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
07191 buf->Skip(len);
07192 } else {
07193 char data = buf->ReadByte();
07194 GRFPalette pal = GRFP_GRF_UNSET;
07195 switch (data) {
07196 case '*':
07197 case 'A': pal = GRFP_GRF_ANY; break;
07198 case 'W': pal = GRFP_GRF_WINDOWS; break;
07199 case 'D': pal = GRFP_GRF_DOS; break;
07200 default:
07201 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
07202 break;
07203 }
07204 if (pal != GRFP_GRF_UNSET) {
07205 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
07206 _cur.grfconfig->palette |= pal;
07207 }
07208 }
07209 return true;
07210 }
07211
07213 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
07214 {
07215 if (len != 1) {
07216 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
07217 buf->Skip(len);
07218 } else {
07219 char data = buf->ReadByte();
07220 GRFPalette pal = GRFP_BLT_UNSET;
07221 switch (data) {
07222 case '8': pal = GRFP_BLT_UNSET; break;
07223 case '3': pal = GRFP_BLT_32BPP; break;
07224 default:
07225 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
07226 return true;
07227 }
07228 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
07229 _cur.grfconfig->palette |= pal;
07230 }
07231 return true;
07232 }
07233
07235 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
07236 {
07237 if (len != 4) {
07238 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
07239 buf->Skip(len);
07240 } else {
07241
07242 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07243 }
07244 return true;
07245 }
07246
07248 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
07249 {
07250 if (len != 4) {
07251 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
07252 buf->Skip(len);
07253 } else {
07254 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07255 if (_cur.grfconfig->version == 0) {
07256 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
07257 _cur.grfconfig->min_loadable_version = 0;
07258 }
07259 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
07260 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
07261 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
07262 }
07263 }
07264 return true;
07265 }
07266
07267 static GRFParameterInfo *_cur_parameter;
07268
07270 static bool ChangeGRFParamName(byte langid, const char *str)
07271 {
07272 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
07273 return true;
07274 }
07275
07277 static bool ChangeGRFParamDescription(byte langid, const char *str)
07278 {
07279 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
07280 return true;
07281 }
07282
07284 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
07285 {
07286 if (len != 1) {
07287 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
07288 buf->Skip(len);
07289 } else {
07290 GRFParameterType type = (GRFParameterType)buf->ReadByte();
07291 if (type < PTYPE_END) {
07292 _cur_parameter->type = type;
07293 } else {
07294 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
07295 }
07296 }
07297 return true;
07298 }
07299
07301 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
07302 {
07303 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
07304 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
07305 buf->Skip(len);
07306 } else if (len != 8) {
07307 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
07308 buf->Skip(len);
07309 } else {
07310 _cur_parameter->min_value = buf->ReadDWord();
07311 _cur_parameter->max_value = buf->ReadDWord();
07312 }
07313 return true;
07314 }
07315
07317 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
07318 {
07319 if (len < 1 || len > 3) {
07320 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
07321 buf->Skip(len);
07322 } else {
07323 byte param_nr = buf->ReadByte();
07324 if (param_nr >= lengthof(_cur.grfconfig->param)) {
07325 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
07326 buf->Skip(len - 1);
07327 } else {
07328 _cur_parameter->param_nr = param_nr;
07329 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
07330 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
07331 }
07332 }
07333
07334 return true;
07335 }
07336
07338 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
07339 {
07340 if (len != 4) {
07341 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
07342 buf->Skip(len);
07343 } else {
07344 _cur_parameter->def_value = buf->ReadDWord();
07345 }
07346 _cur.grfconfig->has_param_defaults = true;
07347 return true;
07348 }
07349
07350 typedef bool (*DataHandler)(size_t, ByteReader *);
07351 typedef bool (*TextHandler)(byte, const char *str);
07352 typedef bool (*BranchHandler)(ByteReader *);
07353
07361 struct AllowedSubtags {
07363 AllowedSubtags() :
07364 id(0),
07365 type(0)
07366 {}
07367
07373 AllowedSubtags(uint32 id, DataHandler handler) :
07374 id(id),
07375 type('B')
07376 {
07377 this->handler.data = handler;
07378 }
07379
07385 AllowedSubtags(uint32 id, TextHandler handler) :
07386 id(id),
07387 type('T')
07388 {
07389 this->handler.text = handler;
07390 }
07391
07397 AllowedSubtags(uint32 id, BranchHandler handler) :
07398 id(id),
07399 type('C')
07400 {
07401 this->handler.call_handler = true;
07402 this->handler.u.branch = handler;
07403 }
07404
07410 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
07411 id(id),
07412 type('C')
07413 {
07414 this->handler.call_handler = false;
07415 this->handler.u.subtags = subtags;
07416 }
07417
07418 uint32 id;
07419 byte type;
07420 union {
07421 DataHandler data;
07422 TextHandler text;
07423 struct {
07424 union {
07425 BranchHandler branch;
07426 AllowedSubtags *subtags;
07427 } u;
07428 bool call_handler;
07429 };
07430 } handler;
07431 };
07432
07433 static bool SkipUnknownInfo(ByteReader *buf, byte type);
07434 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
07435
07442 static bool ChangeGRFParamValueNames(ByteReader *buf)
07443 {
07444 byte type = buf->ReadByte();
07445 while (type != 0) {
07446 uint32 id = buf->ReadDWord();
07447 if (type != 'T' || id > _cur_parameter->max_value) {
07448 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
07449 if (!SkipUnknownInfo(buf, type)) return false;
07450 type = buf->ReadByte();
07451 continue;
07452 }
07453
07454 byte langid = buf->ReadByte();
07455 const char *name_string = buf->ReadString();
07456
07457 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
07458 if (val_name != _cur_parameter->value_names.End()) {
07459 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
07460 } else {
07461 GRFText *list = NULL;
07462 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
07463 _cur_parameter->value_names.Insert(id, list);
07464 }
07465
07466 type = buf->ReadByte();
07467 }
07468 return true;
07469 }
07470
07472 AllowedSubtags _tags_parameters[] = {
07473 AllowedSubtags('NAME', ChangeGRFParamName),
07474 AllowedSubtags('DESC', ChangeGRFParamDescription),
07475 AllowedSubtags('TYPE', ChangeGRFParamType),
07476 AllowedSubtags('LIMI', ChangeGRFParamLimits),
07477 AllowedSubtags('MASK', ChangeGRFParamMask),
07478 AllowedSubtags('VALU', ChangeGRFParamValueNames),
07479 AllowedSubtags('DFLT', ChangeGRFParamDefault),
07480 AllowedSubtags()
07481 };
07482
07489 static bool HandleParameterInfo(ByteReader *buf)
07490 {
07491 byte type = buf->ReadByte();
07492 while (type != 0) {
07493 uint32 id = buf->ReadDWord();
07494 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
07495 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
07496 if (!SkipUnknownInfo(buf, type)) return false;
07497 type = buf->ReadByte();
07498 continue;
07499 }
07500
07501 if (id >= _cur.grfconfig->param_info.Length()) {
07502 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
07503 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
07504 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
07505 }
07506 if (_cur.grfconfig->param_info[id] == NULL) {
07507 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
07508 }
07509 _cur_parameter = _cur.grfconfig->param_info[id];
07510
07511 if (!HandleNodes(buf, _tags_parameters)) return false;
07512 type = buf->ReadByte();
07513 }
07514 return true;
07515 }
07516
07518 AllowedSubtags _tags_info[] = {
07519 AllowedSubtags('NAME', ChangeGRFName),
07520 AllowedSubtags('DESC', ChangeGRFDescription),
07521 AllowedSubtags('URL_', ChangeGRFURL),
07522 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
07523 AllowedSubtags('PALS', ChangeGRFPalette),
07524 AllowedSubtags('BLTR', ChangeGRFBlitter),
07525 AllowedSubtags('VRSN', ChangeGRFVersion),
07526 AllowedSubtags('MINV', ChangeGRFMinVersion),
07527 AllowedSubtags('PARA', HandleParameterInfo),
07528 AllowedSubtags()
07529 };
07530
07532 AllowedSubtags _tags_root[] = {
07533 AllowedSubtags('INFO', _tags_info),
07534 AllowedSubtags()
07535 };
07536
07537
07544 static bool SkipUnknownInfo(ByteReader *buf, byte type)
07545 {
07546
07547 switch (type) {
07548 case 'C': {
07549 byte new_type = buf->ReadByte();
07550 while (new_type != 0) {
07551 buf->ReadDWord();
07552 if (!SkipUnknownInfo(buf, new_type)) return false;
07553 new_type = buf->ReadByte();
07554 }
07555 break;
07556 }
07557
07558 case 'T':
07559 buf->ReadByte();
07560 buf->ReadString();
07561 break;
07562
07563 case 'B': {
07564 uint16 size = buf->ReadWord();
07565 buf->Skip(size);
07566 break;
07567 }
07568
07569 default:
07570 return false;
07571 }
07572
07573 return true;
07574 }
07575
07584 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
07585 {
07586 uint i = 0;
07587 AllowedSubtags *tag;
07588 while ((tag = &subtags[i++])->type != 0) {
07589 if (tag->id != BSWAP32(id) || tag->type != type) continue;
07590 switch (type) {
07591 default: NOT_REACHED();
07592
07593 case 'T': {
07594 byte langid = buf->ReadByte();
07595 return tag->handler.text(langid, buf->ReadString());
07596 }
07597
07598 case 'B': {
07599 size_t len = buf->ReadWord();
07600 if (buf->Remaining() < len) return false;
07601 return tag->handler.data(len, buf);
07602 }
07603
07604 case 'C': {
07605 if (tag->handler.call_handler) {
07606 return tag->handler.u.branch(buf);
07607 }
07608 return HandleNodes(buf, tag->handler.u.subtags);
07609 }
07610 }
07611 }
07612 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
07613 return SkipUnknownInfo(buf, type);
07614 }
07615
07622 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
07623 {
07624 byte type = buf->ReadByte();
07625 while (type != 0) {
07626 uint32 id = buf->ReadDWord();
07627 if (!HandleNode(type, id, buf, subtags)) return false;
07628 type = buf->ReadByte();
07629 }
07630 return true;
07631 }
07632
07637 static void StaticGRFInfo(ByteReader *buf)
07638 {
07639
07640 HandleNodes(buf, _tags_root);
07641 }
07642
07648 static void GRFUnsafe(ByteReader *buf)
07649 {
07650 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
07651
07652
07653 _cur.skip_sprites = -1;
07654 }
07655
07656
07658 static void InitializeGRFSpecial()
07659 {
07660 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
07661 | (1 << 0x0D)
07662 | (1 << 0x0E)
07663 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
07664 | (0 << 0x10)
07665 | (1 << 0x12)
07666 | (1 << 0x13)
07667 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
07668 | (1 << 0x1B)
07669 | (1 << 0x1D)
07670 | (1 << 0x1E);
07671
07672 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
07673 | (1 << 0x08)
07674 | (1 << 0x09)
07675 | (0 << 0x0B)
07676 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
07677 | (1 << 0x12)
07678 | (1 << 0x13)
07679 | (1 << 0x14)
07680 | (1 << 0x16)
07681 | (1 << 0x17)
07682 | (1 << 0x18)
07683 | (1 << 0x19)
07684 | (1 << 0x1A)
07685 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B)
07686 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07687
07688 _ttdpatch_flags[2] = (1 << 0x01)
07689 | (1 << 0x03)
07690 | (1 << 0x0A)
07691 | (0 << 0x0B)
07692 | (0 << 0x0C)
07693 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07694 | (1 << 0x0E)
07695 | (1 << 0x0F)
07696 | (0 << 0x10)
07697 | (0 << 0x11)
07698 | (1 << 0x12)
07699 | (1 << 0x13)
07700 | (1 << 0x14)
07701 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07702 | (1 << 0x16)
07703 | (1 << 0x17)
07704 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07705 | (1 << 0x19)
07706 | (1 << 0x1A)
07707 | (1 << 0x1B)
07708 | (1 << 0x1C)
07709 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07710 | (1 << 0x1E)
07711 | (0 << 0x1F);
07712
07713 _ttdpatch_flags[3] = (0 << 0x00)
07714 | (1 << 0x01)
07715 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07716 | (1 << 0x03)
07717 | (0 << 0x04)
07718 | (1 << 0x05)
07719 | (1 << 0x06)
07720 | (1 << 0x07)
07721 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07722 | (0 << 0x09)
07723 | (0 << 0x0A)
07724 | (1 << 0x0B)
07725 | (1 << 0x0C)
07726 | (1 << 0x0D)
07727 | (1 << 0x0E)
07728 | (1 << 0x0F)
07729 | (1 << 0x10)
07730 | (1 << 0x11)
07731 | (1 << 0x12)
07732 | (0 << 0x13)
07733 | (1 << 0x14)
07734 | (0 << 0x15)
07735 | (1 << 0x16)
07736 | (1 << 0x17)
07737 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07738 | (1 << 0x1E)
07739 | (1 << 0x1F);
07740 }
07741
07743 static void ResetCustomStations()
07744 {
07745 const GRFFile * const *end = _grf_files.End();
07746 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07747 StationSpec **&stations = (*file)->stations;
07748 if (stations == NULL) continue;
07749 for (uint i = 0; i < MAX_STATIONS; i++) {
07750 if (stations[i] == NULL) continue;
07751 StationSpec *statspec = stations[i];
07752
07753 delete[] statspec->renderdata;
07754
07755
07756 if (!statspec->copied_layouts) {
07757 for (uint l = 0; l < statspec->lengths; l++) {
07758 for (uint p = 0; p < statspec->platforms[l]; p++) {
07759 free(statspec->layouts[l][p]);
07760 }
07761 free(statspec->layouts[l]);
07762 }
07763 free(statspec->layouts);
07764 free(statspec->platforms);
07765 }
07766
07767
07768 free(statspec);
07769 }
07770
07771
07772 free(stations);
07773 stations = NULL;
07774 }
07775 }
07776
07778 static void ResetCustomHouses()
07779 {
07780 const GRFFile * const *end = _grf_files.End();
07781 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07782 HouseSpec **&housespec = (*file)->housespec;
07783 if (housespec == NULL) continue;
07784 for (uint i = 0; i < HOUSE_MAX; i++) {
07785 free(housespec[i]);
07786 }
07787
07788 free(housespec);
07789 housespec = NULL;
07790 }
07791 }
07792
07794 static void ResetCustomAirports()
07795 {
07796 const GRFFile * const *end = _grf_files.End();
07797 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07798 AirportSpec **aslist = (*file)->airportspec;
07799 if (aslist != NULL) {
07800 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07801 AirportSpec *as = aslist[i];
07802
07803 if (as != NULL) {
07804
07805 for (int j = 0; j < as->num_table; j++) {
07806
07807 free(as->table[j]);
07808 }
07809 free(as->table);
07810 free(as->depot_table);
07811
07812 free(as);
07813 }
07814 }
07815 free(aslist);
07816 (*file)->airportspec = NULL;
07817 }
07818
07819 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07820 if (airporttilespec != NULL) {
07821 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07822 free(airporttilespec[i]);
07823 }
07824 free(airporttilespec);
07825 airporttilespec = NULL;
07826 }
07827 }
07828 }
07829
07831 static void ResetCustomIndustries()
07832 {
07833 const GRFFile * const *end = _grf_files.End();
07834 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07835 IndustrySpec **&industryspec = (*file)->industryspec;
07836 IndustryTileSpec **&indtspec = (*file)->indtspec;
07837
07838
07839
07840 if (industryspec != NULL) {
07841 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07842 IndustrySpec *ind = industryspec[i];
07843 if (ind == NULL) continue;
07844
07845
07846 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07847 free(ind->random_sounds);
07848 }
07849
07850
07851 CleanIndustryTileTable(ind);
07852
07853 free(ind);
07854 }
07855
07856 free(industryspec);
07857 industryspec = NULL;
07858 }
07859
07860 if (indtspec == NULL) continue;
07861 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07862 free(indtspec[i]);
07863 }
07864
07865 free(indtspec);
07866 indtspec = NULL;
07867 }
07868 }
07869
07871 static void ResetCustomObjects()
07872 {
07873 const GRFFile * const *end = _grf_files.End();
07874 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07875 ObjectSpec **&objectspec = (*file)->objectspec;
07876 if (objectspec == NULL) continue;
07877 for (uint i = 0; i < NUM_OBJECTS; i++) {
07878 free(objectspec[i]);
07879 }
07880
07881 free(objectspec);
07882 objectspec = NULL;
07883 }
07884 }
07885
07887 static void ResetNewGRF()
07888 {
07889 const GRFFile * const *end = _grf_files.End();
07890 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07891 delete *file;
07892 }
07893
07894 _grf_files.Clear();
07895 _cur.grffile = NULL;
07896 }
07897
07899 static void ResetNewGRFErrors()
07900 {
07901 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07902 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07903 delete c->error;
07904 c->error = NULL;
07905 }
07906 }
07907 }
07908
07913 void ResetNewGRFData()
07914 {
07915 CleanUpStrings();
07916 CleanUpGRFTownNames();
07917
07918
07919 SetupEngines();
07920
07921
07922 ResetBridges();
07923
07924
07925 ResetRailTypes();
07926
07927
07928 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07929
07930
07931 Engine *e;
07932 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07933 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07934 }
07935
07936
07937 memset(&_grm_engines, 0, sizeof(_grm_engines));
07938 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
07939
07940
07941 ResetGenericCallbacks();
07942
07943
07944 ResetPriceBaseMultipliers();
07945
07946
07947 ResetCurrencies();
07948
07949
07950 ResetCustomHouses();
07951 ResetHouses();
07952
07953
07954 ResetCustomIndustries();
07955 ResetIndustries();
07956
07957
07958 ObjectClass::Reset();
07959 ResetCustomObjects();
07960 ResetObjects();
07961
07962
07963 StationClass::Reset();
07964 ResetCustomStations();
07965
07966
07967 AirportClass::Reset();
07968 ResetCustomAirports();
07969 AirportSpec::ResetAirports();
07970 AirportTileSpec::ResetAirportTiles();
07971
07972
07973 memset(_water_feature, 0, sizeof(_water_feature));
07974
07975
07976 ClearSnowLine();
07977
07978
07979 ResetNewGRF();
07980
07981
07982 ResetNewGRFErrors();
07983
07984
07985 SetupCargoForClimate(_settings_game.game_creation.landscape);
07986
07987
07988 _misc_grf_features = 0;
07989
07990 _loaded_newgrf_features.has_2CC = false;
07991 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07992 _loaded_newgrf_features.has_newhouses = false;
07993 _loaded_newgrf_features.has_newindustries = false;
07994 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07995
07996
07997 _grf_id_overrides.clear();
07998
07999 InitializeSoundPool();
08000 _spritegroup_pool.CleanPool();
08001 }
08002
08006 void ResetPersistentNewGRFData()
08007 {
08008
08009 _engine_mngr.ResetToDefaultMapping();
08010 _house_mngr.ResetMapping();
08011 _industry_mngr.ResetMapping();
08012 _industile_mngr.ResetMapping();
08013 _airport_mngr.ResetMapping();
08014 _airporttile_mngr.ResetMapping();
08015 }
08016
08021 static void BuildCargoTranslationMap()
08022 {
08023 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
08024
08025 for (CargoID c = 0; c < NUM_CARGO; c++) {
08026 const CargoSpec *cs = CargoSpec::Get(c);
08027 if (!cs->IsValid()) continue;
08028
08029 if (_cur.grffile->cargo_list.Length() == 0) {
08030
08031 _cur.grffile->cargo_map[c] = cs->bitnum;
08032 } else {
08033
08034 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
08035 if (index >= 0) _cur.grffile->cargo_map[c] = index;
08036 }
08037 }
08038 }
08039
08044 static void InitNewGRFFile(const GRFConfig *config)
08045 {
08046 GRFFile *newfile = GetFileByFilename(config->filename);
08047 if (newfile != NULL) {
08048
08049 _cur.grffile = newfile;
08050 return;
08051 }
08052
08053 newfile = new GRFFile(config);
08054 *_grf_files.Append() = _cur.grffile = newfile;
08055 }
08056
08061 GRFFile::GRFFile(const GRFConfig *config)
08062 {
08063 this->filename = strdup(config->filename);
08064 this->grfid = config->ident.grfid;
08065
08066
08067 this->traininfo_vehicle_pitch = 0;
08068 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
08069
08070
08071 for (Price i = PR_BEGIN; i < PR_END; i++) {
08072 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
08073 }
08074
08075
08076 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
08077 this->railtype_map[0] = RAILTYPE_RAIL;
08078 this->railtype_map[1] = RAILTYPE_ELECTRIC;
08079 this->railtype_map[2] = RAILTYPE_MONO;
08080 this->railtype_map[3] = RAILTYPE_MAGLEV;
08081
08082
08083
08084 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
08085
08086 assert(config->num_params <= lengthof(config->param));
08087 this->param_end = config->num_params;
08088 if (this->param_end > 0) {
08089 MemCpyT(this->param, config->param, this->param_end);
08090 }
08091 }
08092
08093 GRFFile::~GRFFile()
08094 {
08095 free(this->filename);
08096 delete[] this->language_map;
08097 }
08098
08099
08104 static const CargoLabel _default_refitmasks_rail[] = {
08105 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
08106 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
08107 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08108 'PLST', 'FZDR',
08109 0 };
08110
08111 static const CargoLabel _default_refitmasks_road[] = {
08112 0 };
08113
08114 static const CargoLabel _default_refitmasks_ships[] = {
08115 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
08116 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
08117 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08118 'PLST', 'FZDR',
08119 0 };
08120
08121 static const CargoLabel _default_refitmasks_aircraft[] = {
08122 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
08123 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
08124 0 };
08125
08126 static const CargoLabel * const _default_refitmasks[] = {
08127 _default_refitmasks_rail,
08128 _default_refitmasks_road,
08129 _default_refitmasks_ships,
08130 _default_refitmasks_aircraft,
08131 };
08132
08133
08137 static void CalculateRefitMasks()
08138 {
08139 Engine *e;
08140
08141 FOR_ALL_ENGINES(e) {
08142 EngineID engine = e->index;
08143 EngineInfo *ei = &e->info;
08144 bool only_defaultcargo;
08145
08146
08147 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
08148 uint32 mask = 0;
08149 uint32 not_mask = 0;
08150 uint32 xor_mask = ei->refit_mask;
08151
08152
08153
08154 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
08155
08156 if (_gted[engine].cargo_allowed != 0) {
08157
08158 const CargoSpec *cs;
08159 FOR_ALL_CARGOSPECS(cs) {
08160 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
08161 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
08162 }
08163 }
08164
08165 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
08166
08167
08168 ei->refit_mask |= _gted[engine].ctt_include_mask;
08169 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
08170 } else {
08171 uint32 xor_mask = 0;
08172
08173
08174 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
08175 const CargoLabel *cl = _default_refitmasks[e->type];
08176 for (uint i = 0;; i++) {
08177 if (cl[i] == 0) break;
08178
08179 CargoID cargo = GetCargoIDByLabel(cl[i]);
08180 if (cargo == CT_INVALID) continue;
08181
08182 SetBit(xor_mask, cargo);
08183 }
08184 }
08185
08186 ei->refit_mask = xor_mask & _cargo_mask;
08187
08188
08189 only_defaultcargo = (ei->refit_mask == 0);
08190 }
08191
08192
08193 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
08194
08195
08196
08197 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
08198 ei->cargo_type = CT_INVALID;
08199 }
08200
08201
08202
08203 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
08204
08205 const uint8 *cargo_map_for_first_refittable = NULL;
08206 {
08207 const GRFFile *file = _gted[engine].defaultcargo_grf;
08208 if (file == NULL) file = e->GetGRF();
08209 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
08210 cargo_map_for_first_refittable = file->cargo_map;
08211 }
08212 }
08213
08214 if (cargo_map_for_first_refittable != NULL) {
08215
08216 byte best_local_slot = 0xFF;
08217 CargoID cargo_type;
08218 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
08219 byte local_slot = cargo_map_for_first_refittable[cargo_type];
08220 if (local_slot < best_local_slot) {
08221 best_local_slot = local_slot;
08222 ei->cargo_type = cargo_type;
08223 }
08224 }
08225 }
08226
08227 if (ei->cargo_type == CT_INVALID) {
08228
08229 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
08230 }
08231 }
08232 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
08233
08234
08235 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
08236 ei->refit_mask = 0;
08237 }
08238 }
08239 }
08240
08242 static void FinaliseCanals()
08243 {
08244 for (uint i = 0; i < CF_END; i++) {
08245 if (_water_feature[i].grffile != NULL) {
08246 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
08247 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
08248 }
08249 }
08250 }
08251
08253 static void FinaliseEngineArray()
08254 {
08255 Engine *e;
08256
08257 FOR_ALL_ENGINES(e) {
08258 if (e->GetGRF() == NULL) {
08259 const EngineIDMapping &eid = _engine_mngr[e->index];
08260 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
08261 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
08262 }
08263 }
08264
08265
08266
08267
08268 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
08269 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
08270 }
08271
08272
08273 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
08274 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
08275 SetBit(_loaded_newgrf_features.used_liveries, ls);
08276
08277
08278 if (e->type == VEH_TRAIN) {
08279 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
08280 switch (ls) {
08281 case LS_STEAM:
08282 case LS_DIESEL:
08283 case LS_ELECTRIC:
08284 case LS_MONORAIL:
08285 case LS_MAGLEV:
08286 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
08287 break;
08288
08289 case LS_DMU:
08290 case LS_EMU:
08291 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
08292 break;
08293
08294 default: NOT_REACHED();
08295 }
08296 }
08297 }
08298 }
08299 }
08300
08302 static void FinaliseCargoArray()
08303 {
08304 for (CargoID c = 0; c < NUM_CARGO; c++) {
08305 CargoSpec *cs = CargoSpec::Get(c);
08306 if (!cs->IsValid()) {
08307 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
08308 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
08309 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
08310 }
08311 }
08312 }
08313
08325 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
08326 {
08327 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
08328 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
08329 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
08330 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
08331 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
08332 hs->enabled = false;
08333 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);
08334 return false;
08335 }
08336
08337
08338
08339
08340 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
08341 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
08342 hs->enabled = false;
08343 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);
08344 return false;
08345 }
08346
08347
08348
08349 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
08350 hs->enabled = false;
08351 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);
08352 return false;
08353 }
08354
08355
08356 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
08357 hs->enabled = false;
08358 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);
08359 return false;
08360 }
08361
08362 return true;
08363 }
08364
08371 static void EnsureEarlyHouse(HouseZones bitmask)
08372 {
08373 Year min_year = MAX_YEAR;
08374
08375 for (int i = 0; i < HOUSE_MAX; i++) {
08376 HouseSpec *hs = HouseSpec::Get(i);
08377 if (hs == NULL || !hs->enabled) continue;
08378 if ((hs->building_availability & bitmask) != bitmask) continue;
08379 if (hs->min_year < min_year) min_year = hs->min_year;
08380 }
08381
08382 if (min_year == 0) return;
08383
08384 for (int i = 0; i < HOUSE_MAX; i++) {
08385 HouseSpec *hs = HouseSpec::Get(i);
08386 if (hs == NULL || !hs->enabled) continue;
08387 if ((hs->building_availability & bitmask) != bitmask) continue;
08388 if (hs->min_year == min_year) hs->min_year = 0;
08389 }
08390 }
08391
08398 static void FinaliseHouseArray()
08399 {
08400
08401
08402
08403
08404
08405
08406
08407
08408
08409 const GRFFile * const *end = _grf_files.End();
08410 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08411 HouseSpec **&housespec = (*file)->housespec;
08412 if (housespec == NULL) continue;
08413
08414 for (int i = 0; i < HOUSE_MAX; i++) {
08415 HouseSpec *hs = housespec[i];
08416
08417 if (hs == NULL) continue;
08418
08419 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
08420 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
08421 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
08422
08423 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
08424
08425 _house_mngr.SetEntitySpec(hs);
08426 }
08427 }
08428
08429 for (int i = 0; i < HOUSE_MAX; i++) {
08430 HouseSpec *hs = HouseSpec::Get(i);
08431 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
08432 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
08433 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
08434
08435
08436
08437 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
08438
08439
08440
08441
08442
08443
08444
08445 hs->building_flags = TILE_NO_FLAG;
08446 }
08447 }
08448
08449 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
08450 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
08451 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
08452 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
08453 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
08454 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
08455
08456 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
08457 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
08458 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
08459 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
08460 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
08461 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
08462 }
08463 }
08464
08470 static void FinaliseIndustriesArray()
08471 {
08472 const GRFFile * const *end = _grf_files.End();
08473 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08474 IndustrySpec **&industryspec = (*file)->industryspec;
08475 IndustryTileSpec **&indtspec = (*file)->indtspec;
08476 if (industryspec != NULL) {
08477 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
08478 IndustrySpec *indsp = industryspec[i];
08479
08480 if (indsp != NULL && indsp->enabled) {
08481 StringID strid;
08482
08483
08484
08485 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
08486 if (strid != STR_UNDEFINED) indsp->name = strid;
08487
08488 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
08489 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
08490
08491 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
08492 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
08493
08494 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
08495 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
08496
08497 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
08498 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
08499
08500 if (indsp->station_name != STR_NULL) {
08501
08502
08503 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
08504 if (strid != STR_UNDEFINED) indsp->station_name = strid;
08505 }
08506
08507 _industry_mngr.SetEntitySpec(indsp);
08508 _loaded_newgrf_features.has_newindustries = true;
08509 }
08510 }
08511 }
08512
08513 if (indtspec != NULL) {
08514 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
08515 IndustryTileSpec *indtsp = indtspec[i];
08516 if (indtsp != NULL) {
08517 _industile_mngr.SetEntitySpec(indtsp);
08518 }
08519 }
08520 }
08521 }
08522
08523 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
08524 IndustrySpec *indsp = &_industry_specs[j];
08525 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
08526 for (uint i = 0; i < 3; i++) {
08527 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
08528 }
08529 }
08530 if (!indsp->enabled) {
08531 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
08532 }
08533 }
08534 }
08535
08541 static void FinaliseObjectsArray()
08542 {
08543 const GRFFile * const *end = _grf_files.End();
08544 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08545 ObjectSpec **&objectspec = (*file)->objectspec;
08546 if (objectspec != NULL) {
08547 for (int i = 0; i < NUM_OBJECTS; i++) {
08548 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
08549 _object_mngr.SetEntitySpec(objectspec[i]);
08550 }
08551 }
08552 }
08553 }
08554 }
08555
08561 static void FinaliseAirportsArray()
08562 {
08563 const GRFFile * const *end = _grf_files.End();
08564 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08565 AirportSpec **&airportspec = (*file)->airportspec;
08566 if (airportspec != NULL) {
08567 for (int i = 0; i < NUM_AIRPORTS; i++) {
08568 if (airportspec[i] != NULL && airportspec[i]->enabled) {
08569 _airport_mngr.SetEntitySpec(airportspec[i]);
08570 }
08571 }
08572 }
08573
08574 AirportTileSpec **&airporttilespec = (*file)->airtspec;
08575 if (airporttilespec != NULL) {
08576 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
08577 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
08578 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
08579 }
08580 }
08581 }
08582 }
08583 }
08584
08585
08586
08587
08588
08589
08590
08591 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
08592 {
08593
08594
08595
08596
08597
08598
08599
08600
08601
08602
08603
08604
08605 static const SpecialSpriteHandler handlers[][GLS_END] = {
08606 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
08607 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
08608 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
08609 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
08610 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
08611 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
08612 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
08613 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
08614 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
08615 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
08616 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
08617 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
08618 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
08619 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
08620 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
08621 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
08622 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
08623 { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
08624 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
08625 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
08626 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
08627 };
08628
08629 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
08630
08631 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
08632 if (it == _grf_line_to_action6_sprite_override.end()) {
08633
08634
08635 FioReadBlock(buf, num);
08636 } else {
08637
08638 buf = _grf_line_to_action6_sprite_override[location];
08639 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
08640
08641
08642 FioSeekTo(num, SEEK_CUR);
08643 }
08644
08645 ByteReader br(buf, buf + num);
08646 ByteReader *bufp = &br;
08647
08648 try {
08649 byte action = bufp->ReadByte();
08650
08651 if (action == 0xFF) {
08652 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
08653 } else if (action == 0xFE) {
08654 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
08655 } else if (action >= lengthof(handlers)) {
08656 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
08657 } else if (handlers[action][stage] == NULL) {
08658 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
08659 } else {
08660 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
08661 handlers[action][stage](bufp);
08662 }
08663 } catch (...) {
08664 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
08665 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
08666 }
08667 }
08668
08669
08671 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
08672
08677 byte GetGRFContainerVersion()
08678 {
08679 size_t pos = FioGetPos();
08680
08681 if (FioReadWord() == 0) {
08682
08683
08684 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
08685 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0;
08686 }
08687
08688 return 2;
08689 }
08690
08691
08692 FioSeekTo(pos, SEEK_SET);
08693 return 1;
08694 }
08695
08703 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
08704 {
08705 const char *filename = config->filename;
08706
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
08717 _cur.grffile = GetFileByFilename(filename);
08718 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
08719 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
08720 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
08721 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
08722 }
08723
08724 if (file_index > LAST_GRF_SLOT) {
08725 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
08726 config->status = GCS_DISABLED;
08727 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
08728 return;
08729 }
08730
08731 FioOpenFile(file_index, filename, subdir);
08732 _cur.file_index = file_index;
08733 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
08734
08735 _cur.grfconfig = config;
08736
08737 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
08738
08739 _cur.grf_container_ver = GetGRFContainerVersion();
08740 if (_cur.grf_container_ver == 0) {
08741 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08742 return;
08743 }
08744
08745 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
08746
08747
08748 ReadGRFSpriteOffsets(_cur.grf_container_ver);
08749 } else {
08750
08751 if (_cur.grf_container_ver >= 2) FioReadDword();
08752 }
08753
08754 if (_cur.grf_container_ver >= 2) {
08755
08756 byte compression = FioReadByte();
08757 if (compression != 0) {
08758 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
08759 return;
08760 }
08761 }
08762
08763
08764
08765
08766 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
08767 if (num == 4 && FioReadByte() == 0xFF) {
08768 FioReadDword();
08769 } else {
08770 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08771 return;
08772 }
08773
08774 _cur.ClearDataForNextFile();
08775
08776 ReusableBuffer<byte> buf;
08777
08778 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
08779 byte type = FioReadByte();
08780 _cur.nfo_line++;
08781
08782 if (type == 0xFF) {
08783 if (_cur.skip_sprites == 0) {
08784 DecodeSpecialSprite(buf.Allocate(num), num, stage);
08785
08786
08787 if (_cur.skip_sprites == -1) break;
08788
08789 continue;
08790 } else {
08791 FioSkipBytes(num);
08792 }
08793 } else {
08794 if (_cur.skip_sprites == 0) {
08795 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08796 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08797 break;
08798 }
08799
08800 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
08801
08802 FioSkipBytes(num);
08803 } else {
08804 FioSkipBytes(7);
08805 SkipSpriteData(type, num - 8);
08806 }
08807 }
08808
08809 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
08810 }
08811 }
08812
08820 static void ActivateOldShore()
08821 {
08822
08823
08824 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08825
08826 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08827 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08828 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08829 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08830 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08831 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08832 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08833 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08834 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08835 }
08836
08837 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08838 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08839 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08840 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08841 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08842 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08843 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08844 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08845 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08846
08847
08848
08849 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08850 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08851 }
08852 }
08853
08857 static void FinalisePriceBaseMultipliers()
08858 {
08859 extern const PriceBaseSpec _price_base_specs[];
08861 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08862
08863
08864 int num_grfs = _grf_files.Length();
08865 int *grf_overrides = AllocaM(int, num_grfs);
08866 for (int i = 0; i < num_grfs; i++) {
08867 grf_overrides[i] = -1;
08868
08869 GRFFile *source = _grf_files[i];
08870 uint32 override = _grf_id_overrides[source->grfid];
08871 if (override == 0) continue;
08872
08873 GRFFile *dest = GetFileByGRFID(override);
08874 if (dest == NULL) continue;
08875
08876 grf_overrides[i] = _grf_files.FindIndex(dest);
08877 assert(grf_overrides[i] >= 0);
08878 }
08879
08880
08881 for (int i = 0; i < num_grfs; i++) {
08882 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08883 GRFFile *source = _grf_files[i];
08884 GRFFile *dest = _grf_files[grf_overrides[i]];
08885
08886 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08887 source->grf_features |= features;
08888 dest->grf_features |= features;
08889
08890 for (Price p = PR_BEGIN; p < PR_END; p++) {
08891
08892 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08893 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08894 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08895 }
08896 }
08897
08898
08899 for (int i = num_grfs - 1; i >= 0; i--) {
08900 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08901 GRFFile *source = _grf_files[i];
08902 GRFFile *dest = _grf_files[grf_overrides[i]];
08903
08904 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08905 source->grf_features |= features;
08906 dest->grf_features |= features;
08907
08908 for (Price p = PR_BEGIN; p < PR_END; p++) {
08909
08910 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08911 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08912 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08913 }
08914 }
08915
08916
08917 for (int i = 0; i < num_grfs; i++) {
08918 if (grf_overrides[i] < 0) continue;
08919 GRFFile *source = _grf_files[i];
08920 GRFFile *dest = _grf_files[grf_overrides[i]];
08921
08922 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08923 source->grf_features |= features;
08924 dest->grf_features |= features;
08925
08926 for (Price p = PR_BEGIN; p < PR_END; p++) {
08927 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08928 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08929 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08930 }
08931 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08932 }
08933 }
08934
08935
08936 const GRFFile * const *end = _grf_files.End();
08937 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08938 if ((*file)->grf_version >= 8) continue;
08939 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08940 for (Price p = PR_BEGIN; p < PR_END; p++) {
08941 Price fallback_price = _price_base_specs[p].fallback_price;
08942 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08943
08944
08945 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08946 }
08947 }
08948 }
08949
08950
08951 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08952 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08953 for (Price p = PR_BEGIN; p < PR_END; p++) {
08954 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08955
08956 price_base_multipliers[p] = 0;
08957 } else {
08958 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08959
08960
08961 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08962 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08963 price_base_multipliers[p] = 0;
08964 } else {
08965 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08966 }
08967 }
08968 }
08969 }
08970 }
08971
08972 void InitDepotWindowBlockSizes();
08973
08974 extern void InitGRFTownGeneratorNames();
08975
08977 static void AfterLoadGRFs()
08978 {
08979 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08980 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08981 }
08982 _string_to_grf_mapping.clear();
08983
08984
08985 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08986 free((*it).second);
08987 }
08988 _grf_line_to_action6_sprite_override.clear();
08989
08990
08991 FinaliseCargoArray();
08992
08993
08994 CalculateRefitMasks();
08995
08996
08997 FinaliseEngineArray();
08998
08999
09000 FinaliseCanals();
09001
09002
09003 InitDepotWindowBlockSizes();
09004
09005
09006 FinaliseHouseArray();
09007
09008
09009 FinaliseIndustriesArray();
09010
09011
09012 FinaliseObjectsArray();
09013
09014 InitializeSortedCargoSpecs();
09015
09016
09017 SortIndustryTypes();
09018
09019
09020 BuildIndustriesLegend();
09021
09022
09023 BuildLinkStatsLegend();
09024
09025
09026 FinaliseAirportsArray();
09027 BindAirportSpecs();
09028
09029
09030 InitGRFTownGeneratorNames();
09031
09032
09033 CommitVehicleListOrderChanges();
09034
09035
09036 ActivateOldShore();
09037
09038
09039 InitRailTypes();
09040
09041 Engine *e;
09042 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
09043 if (_gted[e->index].rv_max_speed != 0) {
09044
09045 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
09046 }
09047 }
09048
09049 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
09050 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
09051 if (railtype == INVALID_RAILTYPE) {
09052
09053 e->info.climates = 0;
09054 } else {
09055 e->u.rail.railtype = railtype;
09056 }
09057 }
09058
09059 SetYearEngineAgingStops();
09060
09061 FinalisePriceBaseMultipliers();
09062
09063
09064 free(_gted);
09065 _grm_sprites.clear();
09066 }
09067
09073 void LoadNewGRF(uint load_index, uint file_index)
09074 {
09075
09076
09077
09078
09079 Date date = _date;
09080 Year year = _cur_year;
09081 DateFract date_fract = _date_fract;
09082 uint16 tick_counter = _tick_counter;
09083 byte display_opt = _display_opt;
09084
09085 if (_networking) {
09086 _cur_year = _settings_game.game_creation.starting_year;
09087 _date = ConvertYMDToDate(_cur_year, 0, 1);
09088 _date_fract = 0;
09089 _tick_counter = 0;
09090 _display_opt = 0;
09091 }
09092
09093 InitializeGRFSpecial();
09094
09095 ResetNewGRFData();
09096
09097
09098
09099
09100
09101
09102
09103
09104 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09105 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
09106 }
09107
09108 _cur.spriteid = load_index;
09109
09110
09111
09112
09113 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
09114
09115
09116 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09117 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
09118 }
09119
09120 if (stage == GLS_RESERVE) {
09121 static const uint32 overrides[][2] = {
09122 { 0x44442202, 0x44440111 },
09123 { 0x6D620402, 0x6D620401 },
09124 { 0x4D656f20, 0x4D656F17 },
09125 };
09126 for (size_t i = 0; i < lengthof(overrides); i++) {
09127 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
09128 }
09129 }
09130
09131 uint slot = file_index;
09132
09133 _cur.stage = stage;
09134 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09135 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
09136 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
09137
09138 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
09139 if (!FioCheckFileExists(c->filename, subdir)) {
09140 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
09141 c->status = GCS_NOT_FOUND;
09142 continue;
09143 }
09144
09145 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
09146 LoadNewGRFFile(c, slot++, stage, subdir);
09147 if (stage == GLS_RESERVE) {
09148 SetBit(c->flags, GCF_RESERVED);
09149 } else if (stage == GLS_ACTIVATION) {
09150 ClrBit(c->flags, GCF_RESERVED);
09151 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
09152 ClearTemporaryNewGRFData(_cur.grffile);
09153 BuildCargoTranslationMap();
09154 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
09155 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
09156
09157 ClearTemporaryNewGRFData(_cur.grffile);
09158 }
09159 }
09160 }
09161
09162
09163 _cur.ClearDataForNextFile();
09164
09165
09166 AfterLoadGRFs();
09167
09168
09169 _cur_year = year;
09170 _date = date;
09171 _date_fract = date_fract;
09172 _tick_counter = tick_counter;
09173 _display_opt = display_opt;
09174 }