newgrf.cpp

Go to the documentation of this file.
00001 /* $Id: newgrf.cpp 25102 2013-03-17 20:58:40Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
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 /* TTDPatch extended GRF format codec
00056  * (c) Petr Baudis 2004 (GPL'd)
00057  * Changes by Florian octo Forster are (c) by the OpenTTD development team.
00058  *
00059  * Contains portions of documentation by TTDPatch team.
00060  * Thanks especially to Josef Drexler for the documentation as well as a lot
00061  * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
00062  * served as subject to the initial testing of this codec. */
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   /* Global state */
00092   GrfLoadingStage stage;    
00093   SpriteID spriteid;        
00094 
00095   /* Local state in the file */
00096   uint file_index;          
00097   GRFFile *grffile;         
00098   GRFConfig *grfconfig;     
00099   uint32 nfo_line;          
00100   byte grf_container_ver;   
00101 
00102   /* Kind of return values when processing certain actions */
00103   int skip_sprites;         
00104 
00105   /* Currently referenceable spritegroups */
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       /* String was not NUL terminated, so make sure it is now. */
00246       string[string_length - 1] = '\0';
00247       grfmsg(7, "String was not terminated with a zero byte.");
00248     } else {
00249       /* Increase the string length to include the NUL byte. */
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     /* It is valid to move the buffer to exactly the end of the data,
00276      * as there may not be any more data read. */
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   /* Clear the GOTO labels used for GRF processing */
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   /* 0xD0 and 0xDC stand for all the TextIDs in the range
00455    * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
00456    * These strings are unique to each grf file, and thus require to be used with the
00457    * grfid in which they are declared */
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       /* Strings embedded via 0x81 have 0x400 added to them (no real
00465        * explanation why...) */
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   /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
00498    * them use the same engine slots. */
00499   uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
00500   if (_settings_game.vehicle.dynamic_engines) {
00501     /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
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     /* Check if the engine is registered in the override manager */
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   /* Check if there is an unreserved slot */
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     /* Reserve the engine slot */
00534     if (!static_access) {
00535       EngineIDMapping *eid = _engine_mngr.Get(engine);
00536       eid->grfid           = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
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   /* ... it's not, so create a new one based off an existing engine */
00552   Engine *e = new Engine(type, internal_id);
00553   e->grf_prop.grffile = file;
00554 
00555   /* Reserve the engine slot */
00556   assert(_engine_mngr.Length() == e->index);
00557   EngineIDMapping *eid = _engine_mngr.Append();
00558   eid->type            = type;
00559   eid->grfid           = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
00560   eid->internal_id     = internal_id;
00561   eid->substitute_id   = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
00562 
00563   if (engine_pool_size != Engine::GetPoolSize()) {
00564     /* Resize temporary engine data ... */
00565     _gted = ReallocT(_gted, Engine::GetPoolSize());
00566 
00567     /* and blank the new block. */
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; // If not using dynamic_engines, all newgrfs share their ID range
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     /* Use sprite from Action 1 */
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     /* Use palette from Action 1 */
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 &regs = 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); // allocate before reading groundsprite flags
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   /* Groundsprite */
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   /* Check if the number of sprites per spriteset is consistent */
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   /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
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 &regs = 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   /* Special value for 'none' */
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: // Introduction date
00902       ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00903       break;
00904 
00905     case 0x02: // Decay speed
00906       ei->decay_speed = buf->ReadByte();
00907       break;
00908 
00909     case 0x03: // Vehicle life
00910       ei->lifelength = buf->ReadByte();
00911       break;
00912 
00913     case 0x04: // Model life
00914       ei->base_life = buf->ReadByte();
00915       break;
00916 
00917     case 0x06: // Climates available
00918       ei->climates = buf->ReadByte();
00919       break;
00920 
00921     case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
00922       /* Amount of cargo loaded during a vehicle's "loading tick" */
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; // No engine could be allocated, so neither can any next vehicles
00948 
00949     EngineInfo *ei = &e->info;
00950     RailVehicleInfo *rvi = &e->u.rail;
00951 
00952     switch (prop) {
00953       case 0x05: { // Track type
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: // AI passenger service
00973         /* Tells the AI that this engine is designed for
00974          * passenger services and shouldn't be used for freight. */
00975         rvi->ai_passenger_only = buf->ReadByte();
00976         break;
00977 
00978       case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
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: // 0x0B Power
00987         rvi->power = buf->ReadWord();
00988 
00989         /* Set engine / wagon state based on power */
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: // 0x0D Running cost factor
01000         rvi->running_cost = buf->ReadByte();
01001         break;
01002 
01003       case 0x0E: // Running cost base
01004         ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
01005         break;
01006 
01007       case 0x12: { // Sprite ID
01008         uint8 spriteid = buf->ReadByte();
01009 
01010         /* TTD sprite IDs point to a location in a 16bit array, but we use it
01011          * as an array index, so we need it to be half the original value. */
01012         if (spriteid < 0xFD) spriteid >>= 1;
01013 
01014         rvi->image_index = spriteid;
01015         break;
01016       }
01017 
01018       case 0x13: { // Dual-headed
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: // 0x14 Cargo capacity
01031         rvi->capacity = buf->ReadByte();
01032         break;
01033 
01034       case 0x15: { // Cargo type
01035         _gted[e->index].defaultcargo_grf = _cur.grffile;
01036         uint8 ctype = buf->ReadByte();
01037 
01038         if (ctype == 0xFF) {
01039           /* 0xFF is specified as 'use first refittable' */
01040           ei->cargo_type = CT_INVALID;
01041         } else if (_cur.grffile->grf_version >= 8) {
01042           /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
01043           ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
01044         } else if (ctype < NUM_CARGO) {
01045           /* Use untranslated cargo. */
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: // 0x16 Weight
01055         SB(rvi->weight, 0, 8, buf->ReadByte());
01056         break;
01057 
01058       case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
01059         rvi->cost_factor = buf->ReadByte();
01060         break;
01061 
01062       case 0x18: // AI rank
01063         grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
01064         buf->ReadByte();
01065         break;
01066 
01067       case 0x19: { // Engine traction type
01068         /* What do the individual numbers mean?
01069          * 0x00 .. 0x07: Steam
01070          * 0x08 .. 0x27: Diesel
01071          * 0x28 .. 0x31: Electric
01072          * 0x32 .. 0x37: Monorail
01073          * 0x38 .. 0x41: Maglev
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           /* Use traction type to select between normal and electrified
01094            * rail only when no translation list is in place. */
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: // Alter purchase list sort order
01104         AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01105         break;
01106 
01107       case 0x1B: // Powered wagons power bonus
01108         rvi->pow_wag_power = buf->ReadWord();
01109         break;
01110 
01111       case 0x1C: // Refit cost
01112         ei->refit_cost = buf->ReadByte();
01113         break;
01114 
01115       case 0x1D: { // Refit cargo
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: // Callback
01124         ei->callback_mask = buf->ReadByte();
01125         break;
01126 
01127       case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
01128         rvi->tractive_effort = buf->ReadByte();
01129         break;
01130 
01131       case 0x20: // Air drag
01132         rvi->air_drag = buf->ReadByte();
01133         break;
01134 
01135       case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
01136         rvi->shorten_factor = buf->ReadByte();
01137         break;
01138 
01139       case 0x22: // Visual effect
01140         rvi->visual_effect = buf->ReadByte();
01141         /* Avoid accidentally setting visual_effect to the default value
01142          * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
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: // Powered wagons weight bonus
01150         rvi->pow_wag_weight = buf->ReadByte();
01151         break;
01152 
01153       case 0x24: { // High byte of vehicle weight
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: // 0x25 User-defined bit mask to set when checking veh. var. 42
01165         rvi->user_def_data = buf->ReadByte();
01166         break;
01167 
01168       case 0x26: // Retire vehicle early
01169         ei->retire_early = buf->ReadByte();
01170         break;
01171 
01172       case 0x27: // Miscellaneous flags
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: // Cargo classes allowed
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: // Cargo classes disallowed
01185         _gted[e->index].cargo_disallowed = buf->ReadWord();
01186         _gted[e->index].UpdateRefittability(false);
01187         break;
01188 
01189       case 0x2A: // Long format introduction date (days since year 0)
01190         ei->base_intro = buf->ReadDWord();
01191         break;
01192 
01193       case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
01194         ei->cargo_age_period = buf->ReadWord();
01195         break;
01196 
01197       case 0x2C:   // CTT refit include list
01198       case 0x2D: { // CTT refit exclude list
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; // No engine could be allocated, so neither can any next vehicles
01236 
01237     EngineInfo *ei = &e->info;
01238     RoadVehicleInfo *rvi = &e->u.road;
01239 
01240     switch (prop) {
01241       case 0x08: // Speed (1 unit is 0.5 kmh)
01242         rvi->max_speed = buf->ReadByte();
01243         break;
01244 
01245       case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
01246         rvi->running_cost = buf->ReadByte();
01247         break;
01248 
01249       case 0x0A: // Running cost base
01250         ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
01251         break;
01252 
01253       case 0x0E: { // Sprite ID
01254         uint8 spriteid = buf->ReadByte();
01255 
01256         /* cars have different custom id in the GRF file */
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: // 0x0F Cargo capacity
01266         rvi->capacity = buf->ReadByte();
01267         break;
01268 
01269       case 0x10: { // Cargo type
01270         _gted[e->index].defaultcargo_grf = _cur.grffile;
01271         uint8 ctype = buf->ReadByte();
01272 
01273         if (ctype == 0xFF) {
01274           /* 0xFF is specified as 'use first refittable' */
01275           ei->cargo_type = CT_INVALID;
01276         } else if (_cur.grffile->grf_version >= 8) {
01277           /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
01278           ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
01279         } else if (ctype < NUM_CARGO) {
01280           /* Use untranslated cargo. */
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: // 0x11 Cost factor
01290         rvi->cost_factor = buf->ReadByte();
01291         break;
01292 
01293       case 0x12: // SFX
01294         rvi->sfx = buf->ReadByte();
01295         break;
01296 
01297       case PROP_ROADVEH_POWER: // Power in units of 10 HP.
01298         rvi->power = buf->ReadByte();
01299         break;
01300 
01301       case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
01302         rvi->weight = buf->ReadByte();
01303         break;
01304 
01305       case PROP_ROADVEH_SPEED: // Speed in mph/0.8
01306         _gted[e->index].rv_max_speed = buf->ReadByte();
01307         break;
01308 
01309       case 0x16: { // Cargoes available for refitting
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: // Callback mask
01318         ei->callback_mask = buf->ReadByte();
01319         break;
01320 
01321       case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
01322         rvi->tractive_effort = buf->ReadByte();
01323         break;
01324 
01325       case 0x19: // Air drag
01326         rvi->air_drag = buf->ReadByte();
01327         break;
01328 
01329       case 0x1A: // Refit cost
01330         ei->refit_cost = buf->ReadByte();
01331         break;
01332 
01333       case 0x1B: // Retire vehicle early
01334         ei->retire_early = buf->ReadByte();
01335         break;
01336 
01337       case 0x1C: // Miscellaneous flags
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: // Cargo classes allowed
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: // Cargo classes disallowed
01349         _gted[e->index].cargo_disallowed = buf->ReadWord();
01350         _gted[e->index].UpdateRefittability(false);
01351         break;
01352 
01353       case 0x1F: // Long format introduction date (days since year 0)
01354         ei->base_intro = buf->ReadDWord();
01355         break;
01356 
01357       case 0x20: // Alter purchase list sort order
01358         AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01359         break;
01360 
01361       case 0x21: // Visual effect
01362         rvi->visual_effect = buf->ReadByte();
01363         /* Avoid accidentally setting visual_effect to the default value
01364          * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
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: // 0x22 Cargo aging period
01372         ei->cargo_age_period = buf->ReadWord();
01373         break;
01374 
01375       case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
01376         rvi->shorten_factor = buf->ReadByte();
01377         break;
01378 
01379       case 0x24:   // CTT refit include list
01380       case 0x25: { // CTT refit exclude list
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; // No engine could be allocated, so neither can any next vehicles
01418 
01419     EngineInfo *ei = &e->info;
01420     ShipVehicleInfo *svi = &e->u.ship;
01421 
01422     switch (prop) {
01423       case 0x08: { // Sprite ID
01424         uint8 spriteid = buf->ReadByte();
01425 
01426         /* ships have different custom id in the GRF file */
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: // Refittable
01436         svi->old_refittable = (buf->ReadByte() != 0);
01437         break;
01438 
01439       case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
01440         svi->cost_factor = buf->ReadByte();
01441         break;
01442 
01443       case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
01444         svi->max_speed = buf->ReadByte();
01445         break;
01446 
01447       case 0x0C: { // Cargo type
01448         _gted[e->index].defaultcargo_grf = _cur.grffile;
01449         uint8 ctype = buf->ReadByte();
01450 
01451         if (ctype == 0xFF) {
01452           /* 0xFF is specified as 'use first refittable' */
01453           ei->cargo_type = CT_INVALID;
01454         } else if (_cur.grffile->grf_version >= 8) {
01455           /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
01456           ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
01457         } else if (ctype < NUM_CARGO) {
01458           /* Use untranslated cargo. */
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: // 0x0D Cargo capacity
01468         svi->capacity = buf->ReadWord();
01469         break;
01470 
01471       case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
01472         svi->running_cost = buf->ReadByte();
01473         break;
01474 
01475       case 0x10: // SFX
01476         svi->sfx = buf->ReadByte();
01477         break;
01478 
01479       case 0x11: { // Cargoes available for refitting
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: // Callback mask
01488         ei->callback_mask = buf->ReadByte();
01489         break;
01490 
01491       case 0x13: // Refit cost
01492         ei->refit_cost = buf->ReadByte();
01493         break;
01494 
01495       case 0x14: // Ocean speed fraction
01496         svi->ocean_speed_frac = buf->ReadByte();
01497         break;
01498 
01499       case 0x15: // Canal speed fraction
01500         svi->canal_speed_frac = buf->ReadByte();
01501         break;
01502 
01503       case 0x16: // Retire vehicle early
01504         ei->retire_early = buf->ReadByte();
01505         break;
01506 
01507       case 0x17: // Miscellaneous flags
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: // Cargo classes allowed
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: // Cargo classes disallowed
01519         _gted[e->index].cargo_disallowed = buf->ReadWord();
01520         _gted[e->index].UpdateRefittability(false);
01521         break;
01522 
01523       case 0x1A: // Long format introduction date (days since year 0)
01524         ei->base_intro = buf->ReadDWord();
01525         break;
01526 
01527       case 0x1B: // Alter purchase list sort order
01528         AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01529         break;
01530 
01531       case 0x1C: // Visual effect
01532         svi->visual_effect = buf->ReadByte();
01533         /* Avoid accidentally setting visual_effect to the default value
01534          * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
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: // 0x1D Cargo aging period
01542         ei->cargo_age_period = buf->ReadWord();
01543         break;
01544 
01545       case 0x1E:   // CTT refit include list
01546       case 0x1F: { // CTT refit exclude list
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; // No engine could be allocated, so neither can any next vehicles
01584 
01585     EngineInfo *ei = &e->info;
01586     AircraftVehicleInfo *avi = &e->u.air;
01587 
01588     switch (prop) {
01589       case 0x08: { // Sprite ID
01590         uint8 spriteid = buf->ReadByte();
01591 
01592         /* aircraft have different custom id in the GRF file */
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: // Helicopter
01602         if (buf->ReadByte() == 0) {
01603           avi->subtype = AIR_HELI;
01604         } else {
01605           SB(avi->subtype, 0, 1, 1); // AIR_CTOL
01606         }
01607         break;
01608 
01609       case 0x0A: // Large
01610         SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
01611         break;
01612 
01613       case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
01614         avi->cost_factor = buf->ReadByte();
01615         break;
01616 
01617       case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
01618         avi->max_speed = (buf->ReadByte() * 128) / 10;
01619         break;
01620 
01621       case 0x0D: { // Acceleration
01622         uint acceleration = (buf->ReadByte() * 128) / 10;
01623         if (acceleration > UINT8_MAX) {
01624           grfmsg(1, "Acceleration property of aircraft %d is too big.", engine + i);
01625           acceleration = UINT8_MAX;
01626         }
01627         avi->acceleration = acceleration;
01628         break;
01629       }
01630 
01631       case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
01632         avi->running_cost = buf->ReadByte();
01633         break;
01634 
01635       case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
01636         avi->passenger_capacity = buf->ReadWord();
01637         break;
01638 
01639       case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
01640         avi->mail_capacity = buf->ReadByte();
01641         break;
01642 
01643       case 0x12: // SFX
01644         avi->sfx = buf->ReadByte();
01645         break;
01646 
01647       case 0x13: { // Cargoes available for refitting
01648         uint32 mask = buf->ReadDWord();
01649         _gted[e->index].UpdateRefittability(mask != 0);
01650         ei->refit_mask = TranslateRefitMask(mask);
01651         _gted[e->index].defaultcargo_grf = _cur.grffile;
01652         break;
01653       }
01654 
01655       case 0x14: // Callback mask
01656         ei->callback_mask = buf->ReadByte();
01657         break;
01658 
01659       case 0x15: // Refit cost
01660         ei->refit_cost = buf->ReadByte();
01661         break;
01662 
01663       case 0x16: // Retire vehicle early
01664         ei->retire_early = buf->ReadByte();
01665         break;
01666 
01667       case 0x17: // Miscellaneous flags
01668         ei->misc_flags = buf->ReadByte();
01669         _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01670         break;
01671 
01672       case 0x18: // Cargo classes allowed
01673         _gted[e->index].cargo_allowed = buf->ReadWord();
01674         _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
01675         _gted[e->index].defaultcargo_grf = _cur.grffile;
01676         break;
01677 
01678       case 0x19: // Cargo classes disallowed
01679         _gted[e->index].cargo_disallowed = buf->ReadWord();
01680         _gted[e->index].UpdateRefittability(false);
01681         break;
01682 
01683       case 0x1A: // Long format introduction date (days since year 0)
01684         ei->base_intro = buf->ReadDWord();
01685         break;
01686 
01687       case 0x1B: // Alter purchase list sort order
01688         AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01689         break;
01690 
01691       case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
01692         ei->cargo_age_period = buf->ReadWord();
01693         break;
01694 
01695       case 0x1D:   // CTT refit include list
01696       case 0x1E: { // CTT refit exclude list
01697         uint8 count = buf->ReadByte();
01698         _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
01699         if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
01700         uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
01701         ctt = 0;
01702         while (count--) {
01703           CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
01704           if (ctype == CT_INVALID) continue;
01705           SetBit(ctt, ctype);
01706         }
01707         break;
01708       }
01709 
01710       case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
01711         avi->max_range = buf->ReadWord();
01712         break;
01713 
01714       default:
01715         ret = CommonVehicleChangeInfo(ei, prop, buf);
01716         break;
01717     }
01718   }
01719 
01720   return ret;
01721 }
01722 
01731 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
01732 {
01733   ChangeInfoResult ret = CIR_SUCCESS;
01734 
01735   if (stid + numinfo > MAX_STATIONS) {
01736     grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
01737     return CIR_INVALID_ID;
01738   }
01739 
01740   /* Allocate station specs if necessary */
01741   if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
01742 
01743   for (int i = 0; i < numinfo; i++) {
01744     StationSpec *statspec = _cur.grffile->stations[stid + i];
01745 
01746     /* Check that the station we are modifying is defined. */
01747     if (statspec == NULL && prop != 0x08) {
01748       grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
01749       return CIR_INVALID_ID;
01750     }
01751 
01752     switch (prop) {
01753       case 0x08: { // Class ID
01754         StationSpec **spec = &_cur.grffile->stations[stid + i];
01755 
01756         /* Property 0x08 is special; it is where the station is allocated */
01757         if (*spec == NULL) *spec = CallocT<StationSpec>(1);
01758 
01759         /* Swap classid because we read it in BE meaning WAYP or DFLT */
01760         uint32 classid = buf->ReadDWord();
01761         (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
01762         break;
01763       }
01764 
01765       case 0x09: // Define sprite layout
01766         statspec->tiles = buf->ReadExtendedByte();
01767         delete[] statspec->renderdata; // delete earlier loaded stuff
01768         statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01769 
01770         for (uint t = 0; t < statspec->tiles; t++) {
01771           NewGRFSpriteLayout *dts = &statspec->renderdata[t];
01772           dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
01773 
01774           if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
01775             buf->Skip(4);
01776             extern const DrawTileSprites _station_display_datas_rail[8];
01777             dts->Clone(&_station_display_datas_rail[t % 8]);
01778             continue;
01779           }
01780 
01781           ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
01782           /* On error, bail out immediately. Temporary GRF data was already freed */
01783           if (_cur.skip_sprites < 0) return CIR_DISABLED;
01784 
01785           static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
01786           tmp_layout.Clear();
01787           for (;;) {
01788             /* no relative bounding box support */
01789             DrawTileSeqStruct *dtss = tmp_layout.Append();
01790             MemSetT(dtss, 0);
01791 
01792             dtss->delta_x = buf->ReadByte();
01793             if (dtss->IsTerminator()) break;
01794             dtss->delta_y = buf->ReadByte();
01795             dtss->delta_z = buf->ReadByte();
01796             dtss->size_x = buf->ReadByte();
01797             dtss->size_y = buf->ReadByte();
01798             dtss->size_z = buf->ReadByte();
01799 
01800             ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
01801             /* On error, bail out immediately. Temporary GRF data was already freed */
01802             if (_cur.skip_sprites < 0) return CIR_DISABLED;
01803           }
01804           dts->Clone(tmp_layout.Begin());
01805         }
01806         break;
01807 
01808       case 0x0A: { // Copy sprite layout
01809         byte srcid = buf->ReadByte();
01810         const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
01811 
01812         if (srcstatspec == NULL) {
01813           grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
01814           continue;
01815         }
01816 
01817         delete[] statspec->renderdata; // delete earlier loaded stuff
01818 
01819         statspec->tiles = srcstatspec->tiles;
01820         statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01821         for (uint t = 0; t < statspec->tiles; t++) {
01822           statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
01823         }
01824         break;
01825       }
01826 
01827       case 0x0B: // Callback mask
01828         statspec->callback_mask = buf->ReadByte();
01829         break;
01830 
01831       case 0x0C: // Disallowed number of platforms
01832         statspec->disallowed_platforms = buf->ReadByte();
01833         break;
01834 
01835       case 0x0D: // Disallowed platform lengths
01836         statspec->disallowed_lengths = buf->ReadByte();
01837         break;
01838 
01839       case 0x0E: // Define custom layout
01840         statspec->copied_layouts = false;
01841 
01842         while (buf->HasData()) {
01843           byte length = buf->ReadByte();
01844           byte number = buf->ReadByte();
01845           StationLayout layout;
01846           uint l, p;
01847 
01848           if (length == 0 || number == 0) break;
01849 
01850           if (length > statspec->lengths) {
01851             statspec->platforms = ReallocT(statspec->platforms, length);
01852             memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
01853 
01854             statspec->layouts = ReallocT(statspec->layouts, length);
01855             memset(statspec->layouts + statspec->lengths, 0,
01856                    (length - statspec->lengths) * sizeof(*statspec->layouts));
01857 
01858             statspec->lengths = length;
01859           }
01860           l = length - 1; // index is zero-based
01861 
01862           if (number > statspec->platforms[l]) {
01863             statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
01864             /* We expect NULL being 0 here, but C99 guarantees that. */
01865             memset(statspec->layouts[l] + statspec->platforms[l], 0,
01866                    (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
01867 
01868             statspec->platforms[l] = number;
01869           }
01870 
01871           p = 0;
01872           layout = MallocT<byte>(length * number);
01873           try {
01874             for (l = 0; l < length; l++) {
01875               for (p = 0; p < number; p++) {
01876                 layout[l * number + p] = buf->ReadByte();
01877               }
01878             }
01879           } catch (...) {
01880             free(layout);
01881             throw;
01882           }
01883 
01884           l--;
01885           p--;
01886           free(statspec->layouts[l][p]);
01887           statspec->layouts[l][p] = layout;
01888         }
01889         break;
01890 
01891       case 0x0F: { // Copy custom layout
01892         byte srcid = buf->ReadByte();
01893         const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
01894 
01895         if (srcstatspec == NULL) {
01896           grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
01897           continue;
01898         }
01899 
01900         statspec->lengths   = srcstatspec->lengths;
01901         statspec->platforms = srcstatspec->platforms;
01902         statspec->layouts   = srcstatspec->layouts;
01903         statspec->copied_layouts = true;
01904         break;
01905       }
01906 
01907       case 0x10: // Little/lots cargo threshold
01908         statspec->cargo_threshold = buf->ReadWord();
01909         break;
01910 
01911       case 0x11: // Pylon placement
01912         statspec->pylons = buf->ReadByte();
01913         break;
01914 
01915       case 0x12: // Cargo types for random triggers
01916         statspec->cargo_triggers = buf->ReadDWord();
01917         if (_cur.grffile->grf_version >= 7) {
01918           statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
01919         }
01920         break;
01921 
01922       case 0x13: // General flags
01923         statspec->flags = buf->ReadByte();
01924         break;
01925 
01926       case 0x14: // Overhead wire placement
01927         statspec->wires = buf->ReadByte();
01928         break;
01929 
01930       case 0x15: // Blocked tiles
01931         statspec->blocked = buf->ReadByte();
01932         break;
01933 
01934       case 0x16: // Animation info
01935         statspec->animation.frames = buf->ReadByte();
01936         statspec->animation.status = buf->ReadByte();
01937         break;
01938 
01939       case 0x17: // Animation speed
01940         statspec->animation.speed = buf->ReadByte();
01941         break;
01942 
01943       case 0x18: // Animation triggers
01944         statspec->animation.triggers = buf->ReadWord();
01945         break;
01946 
01947       case 0x1A: // Advanced sprite layout
01948         statspec->tiles = buf->ReadExtendedByte();
01949         delete[] statspec->renderdata; // delete earlier loaded stuff
01950         statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01951 
01952         for (uint t = 0; t < statspec->tiles; t++) {
01953           NewGRFSpriteLayout *dts = &statspec->renderdata[t];
01954           uint num_building_sprites = buf->ReadByte();
01955           /* On error, bail out immediately. Temporary GRF data was already freed */
01956           if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
01957         }
01958         break;
01959 
01960       default:
01961         ret = CIR_UNKNOWN;
01962         break;
01963     }
01964   }
01965 
01966   return ret;
01967 }
01968 
01977 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
01978 {
01979   ChangeInfoResult ret = CIR_SUCCESS;
01980 
01981   if (id + numinfo > CF_END) {
01982     grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
01983     return CIR_INVALID_ID;
01984   }
01985 
01986   for (int i = 0; i < numinfo; i++) {
01987     CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
01988 
01989     switch (prop) {
01990       case 0x08:
01991         cp->callback_mask = buf->ReadByte();
01992         break;
01993 
01994       case 0x09:
01995         cp->flags = buf->ReadByte();
01996         break;
01997 
01998       default:
01999         ret = CIR_UNKNOWN;
02000         break;
02001     }
02002   }
02003 
02004   return ret;
02005 }
02006 
02015 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
02016 {
02017   ChangeInfoResult ret = CIR_SUCCESS;
02018 
02019   if (brid + numinfo > MAX_BRIDGES) {
02020     grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
02021     return CIR_INVALID_ID;
02022   }
02023 
02024   for (int i = 0; i < numinfo; i++) {
02025     BridgeSpec *bridge = &_bridge[brid + i];
02026 
02027     switch (prop) {
02028       case 0x08: { // Year of availability
02029         /* We treat '0' as always available */
02030         byte year = buf->ReadByte();
02031         bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
02032         break;
02033       }
02034 
02035       case 0x09: // Minimum length
02036         bridge->min_length = buf->ReadByte();
02037         break;
02038 
02039       case 0x0A: // Maximum length
02040         bridge->max_length = buf->ReadByte();
02041         if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
02042         break;
02043 
02044       case 0x0B: // Cost factor
02045         bridge->price = buf->ReadByte();
02046         break;
02047 
02048       case 0x0C: // Maximum speed
02049         bridge->speed = buf->ReadWord();
02050         break;
02051 
02052       case 0x0D: { // Bridge sprite tables
02053         byte tableid = buf->ReadByte();
02054         byte numtables = buf->ReadByte();
02055 
02056         if (bridge->sprite_table == NULL) {
02057           /* Allocate memory for sprite table pointers and zero out */
02058           bridge->sprite_table = CallocT<PalSpriteID*>(7);
02059         }
02060 
02061         for (; numtables-- != 0; tableid++) {
02062           if (tableid >= 7) { // skip invalid data
02063             grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
02064             for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
02065             continue;
02066           }
02067 
02068           if (bridge->sprite_table[tableid] == NULL) {
02069             bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
02070           }
02071 
02072           for (byte sprite = 0; sprite < 32; sprite++) {
02073             SpriteID image = buf->ReadWord();
02074             PaletteID pal  = buf->ReadWord();
02075 
02076             bridge->sprite_table[tableid][sprite].sprite = image;
02077             bridge->sprite_table[tableid][sprite].pal    = pal;
02078 
02079             MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
02080           }
02081         }
02082         break;
02083       }
02084 
02085       case 0x0E: // Flags; bit 0 - disable far pillars
02086         bridge->flags = buf->ReadByte();
02087         break;
02088 
02089       case 0x0F: // Long format year of availability (year since year 0)
02090         bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
02091         break;
02092 
02093       case 0x10: { // purchase string
02094         StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
02095         if (newone != STR_UNDEFINED) bridge->material = newone;
02096         break;
02097       }
02098 
02099       case 0x11: // description of bridge with rails or roads
02100       case 0x12: {
02101         StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
02102         if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
02103         break;
02104       }
02105 
02106       case 0x13: // 16 bits cost multiplier
02107         bridge->price = buf->ReadWord();
02108         break;
02109 
02110       default:
02111         ret = CIR_UNKNOWN;
02112         break;
02113     }
02114   }
02115 
02116   return ret;
02117 }
02118 
02125 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
02126 {
02127   ChangeInfoResult ret = CIR_SUCCESS;
02128 
02129   switch (prop) {
02130     case 0x09:
02131     case 0x0B:
02132     case 0x0C:
02133     case 0x0D:
02134     case 0x0E:
02135     case 0x0F:
02136     case 0x11:
02137     case 0x14:
02138     case 0x15:
02139     case 0x16:
02140     case 0x18:
02141     case 0x19:
02142     case 0x1A:
02143     case 0x1B:
02144     case 0x1C:
02145     case 0x1D:
02146     case 0x1F:
02147       buf->ReadByte();
02148       break;
02149 
02150     case 0x0A:
02151     case 0x10:
02152     case 0x12:
02153     case 0x13:
02154     case 0x21:
02155     case 0x22:
02156       buf->ReadWord();
02157       break;
02158 
02159     case 0x1E:
02160       buf->ReadDWord();
02161       break;
02162 
02163     case 0x17:
02164       for (uint j = 0; j < 4; j++) buf->ReadByte();
02165       break;
02166 
02167     case 0x20: {
02168       byte count = buf->ReadByte();
02169       for (byte j = 0; j < count; j++) buf->ReadByte();
02170       break;
02171     }
02172 
02173     default:
02174       ret = CIR_UNKNOWN;
02175       break;
02176   }
02177   return ret;
02178 }
02179 
02188 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
02189 {
02190   ChangeInfoResult ret = CIR_SUCCESS;
02191 
02192   if (hid + numinfo > HOUSE_MAX) {
02193     grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
02194     return CIR_INVALID_ID;
02195   }
02196 
02197   /* Allocate house specs if they haven't been allocated already. */
02198   if (_cur.grffile->housespec == NULL) {
02199     _cur.grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
02200   }
02201 
02202   for (int i = 0; i < numinfo; i++) {
02203     HouseSpec *housespec = _cur.grffile->housespec[hid + i];
02204 
02205     if (prop != 0x08 && housespec == NULL) {
02206       /* If the house property 08 is not yet set, ignore this property */
02207       ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
02208       if (cir > ret) ret = cir;
02209       continue;
02210     }
02211 
02212     switch (prop) {
02213       case 0x08: { // Substitute building type, and definition of a new house
02214         HouseSpec **house = &_cur.grffile->housespec[hid + i];
02215         byte subs_id = buf->ReadByte();
02216 
02217         if (subs_id == 0xFF) {
02218           /* Instead of defining a new house, a substitute house id
02219            * of 0xFF disables the old house with the current id. */
02220           HouseSpec::Get(hid + i)->enabled = false;
02221           continue;
02222         } else if (subs_id >= NEW_HOUSE_OFFSET) {
02223           /* The substitute id must be one of the original houses. */
02224           grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
02225           continue;
02226         }
02227 
02228         /* Allocate space for this house. */
02229         if (*house == NULL) *house = CallocT<HouseSpec>(1);
02230 
02231         housespec = *house;
02232 
02233         MemCpyT(housespec, HouseSpec::Get(subs_id));
02234 
02235         housespec->enabled = true;
02236         housespec->grf_prop.local_id = hid + i;
02237         housespec->grf_prop.subst_id = subs_id;
02238         housespec->grf_prop.grffile = _cur.grffile;
02239         housespec->random_colour[0] = 0x04;  // those 4 random colours are the base colour
02240         housespec->random_colour[1] = 0x08;  // for all new houses
02241         housespec->random_colour[2] = 0x0C;  // they stand for red, blue, orange and green
02242         housespec->random_colour[3] = 0x06;
02243 
02244         /* Make sure that the third cargo type is valid in this
02245          * climate. This can cause problems when copying the properties
02246          * of a house that accepts food, where the new house is valid
02247          * in the temperate climate. */
02248         if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
02249           housespec->cargo_acceptance[2] = 0;
02250         }
02251 
02252         _loaded_newgrf_features.has_newhouses = true;
02253         break;
02254       }
02255 
02256       case 0x09: // Building flags
02257         housespec->building_flags = (BuildingFlags)buf->ReadByte();
02258         break;
02259 
02260       case 0x0A: { // Availability years
02261         uint16 years = buf->ReadWord();
02262         housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
02263         housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
02264         break;
02265       }
02266 
02267       case 0x0B: // Population
02268         housespec->population = buf->ReadByte();
02269         break;
02270 
02271       case 0x0C: // Mail generation multiplier
02272         housespec->mail_generation = buf->ReadByte();
02273         break;
02274 
02275       case 0x0D: // Passenger acceptance
02276       case 0x0E: // Mail acceptance
02277         housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
02278         break;
02279 
02280       case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
02281         int8 goods = buf->ReadByte();
02282 
02283         /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
02284          * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
02285         CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
02286             ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
02287 
02288         /* Make sure the cargo type is valid in this climate. */
02289         if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
02290 
02291         housespec->accepts_cargo[2] = cid;
02292         housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
02293         break;
02294       }
02295 
02296       case 0x10: // Local authority rating decrease on removal
02297         housespec->remove_rating_decrease = buf->ReadWord();
02298         break;
02299 
02300       case 0x11: // Removal cost multiplier
02301         housespec->removal_cost = buf->ReadByte();
02302         break;
02303 
02304       case 0x12: // Building name ID
02305         housespec->building_name = buf->ReadWord();
02306         _string_to_grf_mapping[&housespec->building_name] = _cur.grffile->grfid;
02307         break;
02308 
02309       case 0x13: // Building availability mask
02310         housespec->building_availability = (HouseZones)buf->ReadWord();
02311         break;
02312 
02313       case 0x14: // House callback mask
02314         housespec->callback_mask |= buf->ReadByte();
02315         break;
02316 
02317       case 0x15: { // House override byte
02318         byte override = buf->ReadByte();
02319 
02320         /* The house being overridden must be an original house. */
02321         if (override >= NEW_HOUSE_OFFSET) {
02322           grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
02323           continue;
02324         }
02325 
02326         _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
02327         break;
02328       }
02329 
02330       case 0x16: // Periodic refresh multiplier
02331         housespec->processing_time = min(buf->ReadByte(), 63);
02332         break;
02333 
02334       case 0x17: // Four random colours to use
02335         for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
02336         break;
02337 
02338       case 0x18: // Relative probability of appearing
02339         housespec->probability = buf->ReadByte();
02340         break;
02341 
02342       case 0x19: // Extra flags
02343         housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
02344         break;
02345 
02346       case 0x1A: // Animation frames
02347         housespec->animation.frames = buf->ReadByte();
02348         housespec->animation.status = GB(housespec->animation.frames, 7, 1);
02349         SB(housespec->animation.frames, 7, 1, 0);
02350         break;
02351 
02352       case 0x1B: // Animation speed
02353         housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
02354         break;
02355 
02356       case 0x1C: // Class of the building type
02357         housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
02358         break;
02359 
02360       case 0x1D: // Callback mask part 2
02361         housespec->callback_mask |= (buf->ReadByte() << 8);
02362         break;
02363 
02364       case 0x1E: { // Accepted cargo types
02365         uint32 cargotypes = buf->ReadDWord();
02366 
02367         /* Check if the cargo types should not be changed */
02368         if (cargotypes == 0xFFFFFFFF) break;
02369 
02370         for (uint j = 0; j < 3; j++) {
02371           /* Get the cargo number from the 'list' */
02372           uint8 cargo_part = GB(cargotypes, 8 * j, 8);
02373           CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
02374 
02375           if (cargo == CT_INVALID) {
02376             /* Disable acceptance of invalid cargo type */
02377             housespec->cargo_acceptance[j] = 0;
02378           } else {
02379             housespec->accepts_cargo[j] = cargo;
02380           }
02381         }
02382         break;
02383       }
02384 
02385       case 0x1F: // Minimum life span
02386         housespec->minimum_life = buf->ReadByte();
02387         break;
02388 
02389       case 0x20: { // Cargo acceptance watch list
02390         byte count = buf->ReadByte();
02391         for (byte j = 0; j < count; j++) {
02392           CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
02393           if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
02394         }
02395         break;
02396       }
02397 
02398       case 0x21: // long introduction year
02399         housespec->min_year = buf->ReadWord();
02400         break;
02401 
02402       case 0x22: // long maximum year
02403         housespec->max_year = buf->ReadWord();
02404         break;
02405 
02406       default:
02407         ret = CIR_UNKNOWN;
02408         break;
02409     }
02410   }
02411 
02412   return ret;
02413 }
02414 
02421 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
02422 {
02423   /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
02424   const GRFFile *grffile = GetFileByGRFID(grfid);
02425   return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
02426 }
02427 
02437 template <typename T>
02438 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
02439 {
02440   if (gvid != 0) {
02441     grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
02442     return CIR_INVALID_ID;
02443   }
02444 
02445   translation_table.Clear();
02446   for (int i = 0; i < numinfo; i++) {
02447     uint32 item = buf->ReadDWord();
02448     *translation_table.Append() = BSWAP32(item);
02449   }
02450 
02451   return CIR_SUCCESS;
02452 }
02453 
02462 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
02463 {
02464   /* Properties which are handled as a whole */
02465   switch (prop) {
02466     case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
02467       return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
02468 
02469     case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
02470       return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
02471 
02472     default:
02473       break;
02474   }
02475 
02476   /* Properties which are handled per item */
02477   ChangeInfoResult ret = CIR_SUCCESS;
02478   for (int i = 0; i < numinfo; i++) {
02479     switch (prop) {
02480       case 0x08: { // Cost base factor
02481         int factor = buf->ReadByte();
02482         uint price = gvid + i;
02483 
02484         if (price < PR_END) {
02485           _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
02486         } else {
02487           grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
02488         }
02489         break;
02490       }
02491 
02492       case 0x0A: { // Currency display names
02493         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02494         StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
02495 
02496         if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
02497           _currency_specs[curidx].name = newone;
02498         }
02499         break;
02500       }
02501 
02502       case 0x0B: { // Currency multipliers
02503         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02504         uint32 rate = buf->ReadDWord();
02505 
02506         if (curidx < NUM_CURRENCY) {
02507           /* TTDPatch uses a multiple of 1000 for its conversion calculations,
02508            * which OTTD does not. For this reason, divide grf value by 1000,
02509            * to be compatible */
02510           _currency_specs[curidx].rate = rate / 1000;
02511         } else {
02512           grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
02513         }
02514         break;
02515       }
02516 
02517       case 0x0C: { // Currency options
02518         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02519         uint16 options = buf->ReadWord();
02520 
02521         if (curidx < NUM_CURRENCY) {
02522           _currency_specs[curidx].separator[0] = GB(options, 0, 8);
02523           _currency_specs[curidx].separator[1] = '\0';
02524           /* By specifying only one bit, we prevent errors,
02525            * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
02526           _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
02527         } else {
02528           grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
02529         }
02530         break;
02531       }
02532 
02533       case 0x0D: { // Currency prefix symbol
02534         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02535         uint32 tempfix = buf->ReadDWord();
02536 
02537         if (curidx < NUM_CURRENCY) {
02538           memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
02539           _currency_specs[curidx].prefix[4] = 0;
02540         } else {
02541           grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
02542         }
02543         break;
02544       }
02545 
02546       case 0x0E: { // Currency suffix symbol
02547         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02548         uint32 tempfix = buf->ReadDWord();
02549 
02550         if (curidx < NUM_CURRENCY) {
02551           memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
02552           _currency_specs[curidx].suffix[4] = 0;
02553         } else {
02554           grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
02555         }
02556         break;
02557       }
02558 
02559       case 0x0F: { //  Euro introduction dates
02560         uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
02561         Year year_euro = buf->ReadWord();
02562 
02563         if (curidx < NUM_CURRENCY) {
02564           _currency_specs[curidx].to_euro = year_euro;
02565         } else {
02566           grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
02567         }
02568         break;
02569       }
02570 
02571       case 0x10: // Snow line height table
02572         if (numinfo > 1 || IsSnowLineSet()) {
02573           grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
02574         } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
02575           grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
02576         } else {
02577           byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
02578 
02579           for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
02580             for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
02581               table[i][j] = buf->ReadByte();
02582               if (_cur.grffile->grf_version >= 8) {
02583                 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 256;
02584               } else {
02585                 if (table[i][j] >= 128) {
02586                   /* no snow */
02587                   table[i][j] = 0xFF;
02588                 } else {
02589                   table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 128;
02590                 }
02591               }
02592             }
02593           }
02594           SetSnowLine(table);
02595         }
02596         break;
02597 
02598       case 0x11: // GRF match for engine allocation
02599         /* This is loaded during the reservation stage, so just skip it here. */
02600         /* Each entry is 8 bytes. */
02601         buf->Skip(8);
02602         break;
02603 
02604       case 0x13:   // Gender translation table
02605       case 0x14:   // Case translation table
02606       case 0x15: { // Plural form translation
02607         uint curidx = gvid + i; // The current index, i.e. language.
02608         const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
02609         if (lang == NULL) {
02610           grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
02611           /* Skip over the data. */
02612           if (prop == 0x15) {
02613             buf->ReadByte();
02614           } else {
02615             while (buf->ReadByte() != 0) {
02616               buf->ReadString();
02617             }
02618           }
02619           break;
02620         }
02621 
02622         if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
02623 
02624         if (prop == 0x15) {
02625           uint plural_form = buf->ReadByte();
02626           if (plural_form >= LANGUAGE_MAX_PLURAL) {
02627             grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
02628           } else {
02629             _cur.grffile->language_map[curidx].plural_form = plural_form;
02630           }
02631           break;
02632         }
02633 
02634         byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
02635         while (newgrf_id != 0) {
02636           const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
02637 
02638           /* We'll just ignore the UTF8 identifier character. This is (fairly)
02639            * safe as OpenTTD's strings gender/cases are usually in ASCII which
02640            * is just a subset of UTF8, or they need the bigger UTF8 characters
02641            * such as Cyrillic. Thus we will simply assume they're all UTF8. */
02642           WChar c;
02643           size_t len = Utf8Decode(&c, name);
02644           if (c == NFO_UTF8_IDENTIFIER) name += len;
02645 
02646           LanguageMap::Mapping map;
02647           map.newgrf_id = newgrf_id;
02648           if (prop == 0x13) {
02649             map.openttd_id = lang->GetGenderIndex(name);
02650             if (map.openttd_id >= MAX_NUM_GENDERS) {
02651               grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
02652             } else {
02653               *_cur.grffile->language_map[curidx].gender_map.Append() = map;
02654             }
02655           } else {
02656             map.openttd_id = lang->GetCaseIndex(name);
02657             if (map.openttd_id >= MAX_NUM_CASES) {
02658               grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
02659             } else {
02660               *_cur.grffile->language_map[curidx].case_map.Append() = map;
02661             }
02662           }
02663           newgrf_id = buf->ReadByte();
02664         }
02665         break;
02666       }
02667 
02668       default:
02669         ret = CIR_UNKNOWN;
02670         break;
02671     }
02672   }
02673 
02674   return ret;
02675 }
02676 
02677 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
02678 {
02679   /* Properties which are handled as a whole */
02680   switch (prop) {
02681     case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
02682       return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
02683 
02684     case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
02685       return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
02686 
02687     default:
02688       break;
02689   }
02690 
02691   /* Properties which are handled per item */
02692   ChangeInfoResult ret = CIR_SUCCESS;
02693   for (int i = 0; i < numinfo; i++) {
02694     switch (prop) {
02695       case 0x08: // Cost base factor
02696       case 0x15: // Plural form translation
02697         buf->ReadByte();
02698         break;
02699 
02700       case 0x0A: // Currency display names
02701       case 0x0C: // Currency options
02702       case 0x0F: // Euro introduction dates
02703         buf->ReadWord();
02704         break;
02705 
02706       case 0x0B: // Currency multipliers
02707       case 0x0D: // Currency prefix symbol
02708       case 0x0E: // Currency suffix symbol
02709         buf->ReadDWord();
02710         break;
02711 
02712       case 0x10: // Snow line height table
02713         buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
02714         break;
02715 
02716       case 0x11: { // GRF match for engine allocation
02717         uint32 s = buf->ReadDWord();
02718         uint32 t = buf->ReadDWord();
02719         SetNewGRFOverride(s, t);
02720         break;
02721       }
02722 
02723       case 0x13: // Gender translation table
02724       case 0x14: // Case translation table
02725         while (buf->ReadByte() != 0) {
02726           buf->ReadString();
02727         }
02728         break;
02729 
02730       default:
02731         ret = CIR_UNKNOWN;
02732         break;
02733     }
02734   }
02735 
02736   return ret;
02737 }
02738 
02739 
02748 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
02749 {
02750   ChangeInfoResult ret = CIR_SUCCESS;
02751 
02752   if (cid + numinfo > NUM_CARGO) {
02753     grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
02754     return CIR_INVALID_ID;
02755   }
02756 
02757   for (int i = 0; i < numinfo; i++) {
02758     CargoSpec *cs = CargoSpec::Get(cid + i);
02759 
02760     switch (prop) {
02761       case 0x08: // Bit number of cargo
02762         cs->bitnum = buf->ReadByte();
02763         if (cs->IsValid()) {
02764           cs->grffile = _cur.grffile;
02765           SetBit(_cargo_mask, cid + i);
02766         } else {
02767           ClrBit(_cargo_mask, cid + i);
02768         }
02769         break;
02770 
02771       case 0x09: // String ID for cargo type name
02772         cs->name = buf->ReadWord();
02773         _string_to_grf_mapping[&cs->name] = _cur.grffile->grfid;
02774         break;
02775 
02776       case 0x0A: // String for 1 unit of cargo
02777         cs->name_single = buf->ReadWord();
02778         _string_to_grf_mapping[&cs->name_single] = _cur.grffile->grfid;
02779         break;
02780 
02781       case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
02782       case 0x1B: // String for cargo units
02783         /* String for units of cargo. This is different in OpenTTD
02784          * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
02785          * Property 1B is used to set OpenTTD's behaviour. */
02786         cs->units_volume = buf->ReadWord();
02787         _string_to_grf_mapping[&cs->units_volume] = _cur.grffile->grfid;
02788         break;
02789 
02790       case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
02791       case 0x1C: // String for any amount of cargo
02792         /* Strings for an amount of cargo. This is different in OpenTTD
02793          * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
02794          * Property 1C is used to set OpenTTD's behaviour. */
02795         cs->quantifier = buf->ReadWord();
02796         _string_to_grf_mapping[&cs->quantifier] = _cur.grffile->grfid;
02797         break;
02798 
02799       case 0x0D: // String for two letter cargo abbreviation
02800         cs->abbrev = buf->ReadWord();
02801         _string_to_grf_mapping[&cs->abbrev] = _cur.grffile->grfid;
02802         break;
02803 
02804       case 0x0E: // Sprite ID for cargo icon
02805         cs->sprite = buf->ReadWord();
02806         break;
02807 
02808       case 0x0F: // Weight of one unit of cargo
02809         cs->weight = buf->ReadByte();
02810         break;
02811 
02812       case 0x10: // Used for payment calculation
02813         cs->transit_days[0] = buf->ReadByte();
02814         break;
02815 
02816       case 0x11: // Used for payment calculation
02817         cs->transit_days[1] = buf->ReadByte();
02818         break;
02819 
02820       case 0x12: // Base cargo price
02821         cs->initial_payment = buf->ReadDWord();
02822         break;
02823 
02824       case 0x13: // Colour for station rating bars
02825         cs->rating_colour = buf->ReadByte();
02826         break;
02827 
02828       case 0x14: // Colour for cargo graph
02829         cs->legend_colour = buf->ReadByte();
02830         break;
02831 
02832       case 0x15: // Freight status
02833         cs->is_freight = (buf->ReadByte() != 0);
02834         break;
02835 
02836       case 0x16: // Cargo classes
02837         cs->classes = buf->ReadWord();
02838         break;
02839 
02840       case 0x17: // Cargo label
02841         cs->label = buf->ReadDWord();
02842         cs->label = BSWAP32(cs->label);
02843         break;
02844 
02845       case 0x18: { // Town growth substitute type
02846         uint8 substitute_type = buf->ReadByte();
02847 
02848         switch (substitute_type) {
02849           case 0x00: cs->town_effect = TE_PASSENGERS; break;
02850           case 0x02: cs->town_effect = TE_MAIL; break;
02851           case 0x05: cs->town_effect = TE_GOODS; break;
02852           case 0x09: cs->town_effect = TE_WATER; break;
02853           case 0x0B: cs->town_effect = TE_FOOD; break;
02854           default:
02855             grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
02856           case 0xFF: cs->town_effect = TE_NONE; break;
02857         }
02858         break;
02859       }
02860 
02861       case 0x19: // Town growth coefficient
02862         cs->multipliertowngrowth = buf->ReadWord();
02863         break;
02864 
02865       case 0x1A: // Bitmask of callbacks to use
02866         cs->callback_mask = buf->ReadByte();
02867         break;
02868 
02869       case 0x1D: // Vehicle capacity muliplier
02870         cs->multiplier = max<uint16>(1u, buf->ReadWord());
02871         break;
02872 
02873       default:
02874         ret = CIR_UNKNOWN;
02875         break;
02876     }
02877   }
02878 
02879   return ret;
02880 }
02881 
02882 
02891 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02892 {
02893   ChangeInfoResult ret = CIR_SUCCESS;
02894 
02895   if (_cur.grffile->sound_offset == 0) {
02896     grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02897     return CIR_INVALID_ID;
02898   }
02899 
02900   if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
02901     grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
02902     return CIR_INVALID_ID;
02903   }
02904 
02905   for (int i = 0; i < numinfo; i++) {
02906     SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
02907 
02908     switch (prop) {
02909       case 0x08: // Relative volume
02910         sound->volume = buf->ReadByte();
02911         break;
02912 
02913       case 0x09: // Priority
02914         sound->priority = buf->ReadByte();
02915         break;
02916 
02917       case 0x0A: { // Override old sound
02918         SoundID orig_sound = buf->ReadByte();
02919 
02920         if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02921           grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02922         } else {
02923           SoundEntry *old_sound = GetSound(orig_sound);
02924 
02925           /* Literally copy the data of the new sound over the original */
02926           *old_sound = *sound;
02927         }
02928         break;
02929       }
02930 
02931       default:
02932         ret = CIR_UNKNOWN;
02933         break;
02934     }
02935   }
02936 
02937   return ret;
02938 }
02939 
02946 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
02947 {
02948   ChangeInfoResult ret = CIR_SUCCESS;
02949 
02950   switch (prop) {
02951     case 0x09:
02952     case 0x0D:
02953     case 0x0E:
02954     case 0x10:
02955     case 0x11:
02956     case 0x12:
02957       buf->ReadByte();
02958       break;
02959 
02960     case 0x0A:
02961     case 0x0B:
02962     case 0x0C:
02963     case 0x0F:
02964       buf->ReadWord();
02965       break;
02966 
02967     default:
02968       ret = CIR_UNKNOWN;
02969       break;
02970   }
02971   return ret;
02972 }
02973 
02982 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02983 {
02984   ChangeInfoResult ret = CIR_SUCCESS;
02985 
02986   if (indtid + numinfo > NUM_INDUSTRYTILES) {
02987     grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02988     return CIR_INVALID_ID;
02989   }
02990 
02991   /* Allocate industry tile specs if they haven't been allocated already. */
02992   if (_cur.grffile->indtspec == NULL) {
02993     _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02994   }
02995 
02996   for (int i = 0; i < numinfo; i++) {
02997     IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
02998 
02999     if (prop != 0x08 && tsp == NULL) {
03000       ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
03001       if (cir > ret) ret = cir;
03002       continue;
03003     }
03004 
03005     switch (prop) {
03006       case 0x08: { // Substitute industry tile type
03007         IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
03008         byte subs_id = buf->ReadByte();
03009 
03010         if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
03011           /* The substitute id must be one of the original industry tile. */
03012           grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
03013           continue;
03014         }
03015 
03016         /* Allocate space for this industry. */
03017         if (*tilespec == NULL) {
03018           *tilespec = CallocT<IndustryTileSpec>(1);
03019           tsp = *tilespec;
03020 
03021           memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
03022           tsp->enabled = true;
03023 
03024           /* A copied tile should not have the animation infos copied too.
03025            * The anim_state should be left untouched, though
03026            * It is up to the author to animate them himself */
03027           tsp->anim_production = INDUSTRYTILE_NOANIM;
03028           tsp->anim_next = INDUSTRYTILE_NOANIM;
03029 
03030           tsp->grf_prop.local_id = indtid + i;
03031           tsp->grf_prop.subst_id = subs_id;
03032           tsp->grf_prop.grffile = _cur.grffile;
03033           _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
03034         }
03035         break;
03036       }
03037 
03038       case 0x09: { // Industry tile override
03039         byte ovrid = buf->ReadByte();
03040 
03041         /* The industry being overridden must be an original industry. */
03042         if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
03043           grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
03044           continue;
03045         }
03046 
03047         _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
03048         break;
03049       }
03050 
03051       case 0x0A: // Tile acceptance
03052       case 0x0B:
03053       case 0x0C: {
03054         uint16 acctp = buf->ReadWord();
03055         tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
03056         tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
03057         break;
03058       }
03059 
03060       case 0x0D: // Land shape flags
03061         tsp->slopes_refused = (Slope)buf->ReadByte();
03062         break;
03063 
03064       case 0x0E: // Callback mask
03065         tsp->callback_mask = buf->ReadByte();
03066         break;
03067 
03068       case 0x0F: // Animation information
03069         tsp->animation.frames = buf->ReadByte();
03070         tsp->animation.status = buf->ReadByte();
03071         break;
03072 
03073       case 0x10: // Animation speed
03074         tsp->animation.speed = buf->ReadByte();
03075         break;
03076 
03077       case 0x11: // Triggers for callback 25
03078         tsp->animation.triggers = buf->ReadByte();
03079         break;
03080 
03081       case 0x12: // Special flags
03082         tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
03083         break;
03084 
03085       default:
03086         ret = CIR_UNKNOWN;
03087         break;
03088     }
03089   }
03090 
03091   return ret;
03092 }
03093 
03100 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
03101 {
03102   ChangeInfoResult ret = CIR_SUCCESS;
03103 
03104   switch (prop) {
03105     case 0x09:
03106     case 0x0B:
03107     case 0x0F:
03108     case 0x12:
03109     case 0x13:
03110     case 0x14:
03111     case 0x17:
03112     case 0x18:
03113     case 0x19:
03114     case 0x21:
03115     case 0x22:
03116       buf->ReadByte();
03117       break;
03118 
03119     case 0x0C:
03120     case 0x0D:
03121     case 0x0E:
03122     case 0x10:
03123     case 0x1B:
03124     case 0x1F:
03125     case 0x24:
03126       buf->ReadWord();
03127       break;
03128 
03129     case 0x11:
03130     case 0x1A:
03131     case 0x1C:
03132     case 0x1D:
03133     case 0x1E:
03134     case 0x20:
03135     case 0x23:
03136       buf->ReadDWord();
03137       break;
03138 
03139     case 0x0A: {
03140       byte num_table = buf->ReadByte();
03141       for (byte j = 0; j < num_table; j++) {
03142         for (uint k = 0;; k++) {
03143           byte x = buf->ReadByte();
03144           if (x == 0xFE && k == 0) {
03145             buf->ReadByte();
03146             buf->ReadByte();
03147             break;
03148           }
03149 
03150           byte y = buf->ReadByte();
03151           if (x == 0 && y == 0x80) break;
03152 
03153           byte gfx = buf->ReadByte();
03154           if (gfx == 0xFE) buf->ReadWord();
03155         }
03156       }
03157       break;
03158     }
03159 
03160     case 0x16:
03161       for (byte j = 0; j < 3; j++) buf->ReadByte();
03162       break;
03163 
03164     case 0x15: {
03165       byte number_of_sounds = buf->ReadByte();
03166       for (uint8 j = 0; j < number_of_sounds; j++) {
03167         buf->ReadByte();
03168       }
03169       break;
03170     }
03171 
03172     default:
03173       ret = CIR_UNKNOWN;
03174       break;
03175   }
03176   return ret;
03177 }
03178 
03185 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
03186 {
03187   for (int i = 0; i < size - 1; i++) {
03188     for (int j = i + 1; j < size; j++) {
03189       if (layout[i].ti.x == layout[j].ti.x &&
03190           layout[i].ti.y == layout[j].ti.y) {
03191         return false;
03192       }
03193     }
03194   }
03195   return true;
03196 }
03197 
03199 static void CleanIndustryTileTable(IndustrySpec *ind)
03200 {
03201   if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
03202     for (int j = 0; j < ind->num_table; j++) {
03203       /* remove the individual layouts */
03204       free(ind->table[j]);
03205     }
03206     /* remove the layouts pointers */
03207     free(ind->table);
03208     ind->table = NULL;
03209   }
03210 }
03211 
03220 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
03221 {
03222   ChangeInfoResult ret = CIR_SUCCESS;
03223 
03224   if (indid + numinfo > NUM_INDUSTRYTYPES) {
03225     grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
03226     return CIR_INVALID_ID;
03227   }
03228 
03229   /* Allocate industry specs if they haven't been allocated already. */
03230   if (_cur.grffile->industryspec == NULL) {
03231     _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
03232   }
03233 
03234   for (int i = 0; i < numinfo; i++) {
03235     IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
03236 
03237     if (prop != 0x08 && indsp == NULL) {
03238       ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
03239       if (cir > ret) ret = cir;
03240       continue;
03241     }
03242 
03243     switch (prop) {
03244       case 0x08: { // Substitute industry type
03245         IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
03246         byte subs_id = buf->ReadByte();
03247 
03248         if (subs_id == 0xFF) {
03249           /* Instead of defining a new industry, a substitute industry id
03250            * of 0xFF disables the old industry with the current id. */
03251           _industry_specs[indid + i].enabled = false;
03252           continue;
03253         } else if (subs_id >= NEW_INDUSTRYOFFSET) {
03254           /* The substitute id must be one of the original industry. */
03255           grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
03256           continue;
03257         }
03258 
03259         /* Allocate space for this industry.
03260          * Only need to do it once. If ever it is called again, it should not
03261          * do anything */
03262         if (*indspec == NULL) {
03263           *indspec = CallocT<IndustrySpec>(1);
03264           indsp = *indspec;
03265 
03266           memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
03267           indsp->enabled = true;
03268           indsp->grf_prop.local_id = indid + i;
03269           indsp->grf_prop.subst_id = subs_id;
03270           indsp->grf_prop.grffile = _cur.grffile;
03271           /* If the grf industry needs to check its surounding upon creation, it should
03272            * rely on callbacks, not on the original placement functions */
03273           indsp->check_proc = CHECK_NOTHING;
03274         }
03275         break;
03276       }
03277 
03278       case 0x09: { // Industry type override
03279         byte ovrid = buf->ReadByte();
03280 
03281         /* The industry being overridden must be an original industry. */
03282         if (ovrid >= NEW_INDUSTRYOFFSET) {
03283           grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
03284           continue;
03285         }
03286         indsp->grf_prop.override = ovrid;
03287         _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
03288         break;
03289       }
03290 
03291       case 0x0A: { // Set industry layout(s)
03292         byte new_num_layouts = buf->ReadByte(); // Number of layaouts
03293         /* We read the total size in bytes, but we can't rely on the
03294          * newgrf to provide a sane value. First assume the value is
03295          * sane but later on we make sure we enlarge the array if the
03296          * newgrf contains more data. Each tile uses either 3 or 5
03297          * bytes, so to play it safe we assume 3. */
03298         uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
03299         IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
03300         IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
03301         uint size;
03302         const IndustryTileTable *copy_from;
03303 
03304         try {
03305           for (byte j = 0; j < new_num_layouts; j++) {
03306             for (uint k = 0;; k++) {
03307               if (k >= def_num_tiles) {
03308                 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
03309                 /* Size reported by newgrf was not big enough so enlarge the array. */
03310                 def_num_tiles *= 2;
03311                 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
03312               }
03313 
03314               itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
03315 
03316               if (itt[k].ti.x == 0xFE && k == 0) {
03317                 /* This means we have to borrow the layout from an old industry */
03318                 IndustryType type = buf->ReadByte();  // industry holding required layout
03319                 byte laynbr = buf->ReadByte();        // layout number to borrow
03320 
03321                 copy_from = _origin_industry_specs[type].table[laynbr];
03322                 for (size = 1;; size++) {
03323                   if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
03324                 }
03325                 break;
03326               }
03327 
03328               itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
03329 
03330               if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
03331                 /*  Not the same terminator.  The one we are using is rather
03332                  x = -80, y = x .  So, adjust it. */
03333                 itt[k].ti.x = -0x80;
03334                 itt[k].ti.y =  0;
03335                 itt[k].gfx  =  0;
03336 
03337                 size = k + 1;
03338                 copy_from = itt;
03339                 break;
03340               }
03341 
03342               itt[k].gfx = buf->ReadByte();
03343 
03344               if (itt[k].gfx == 0xFE) {
03345                 /* Use a new tile from this GRF */
03346                 int local_tile_id = buf->ReadWord();
03347 
03348                 /* Read the ID from the _industile_mngr. */
03349                 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
03350 
03351                 if (tempid == INVALID_INDUSTRYTILE) {
03352                   grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
03353                 } else {
03354                   /* Declared as been valid, can be used */
03355                   itt[k].gfx = tempid;
03356                   size = k + 1;
03357                   copy_from = itt;
03358                 }
03359               } else if (itt[k].gfx == 0xFF) {
03360                 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
03361                 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
03362               }
03363             }
03364 
03365             if (!ValidateIndustryLayout(copy_from, size)) {
03366               /* The industry layout was not valid, so skip this one. */
03367               grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
03368               new_num_layouts--;
03369               j--;
03370             } else {
03371               tile_table[j] = CallocT<IndustryTileTable>(size);
03372               memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03373             }
03374           }
03375         } catch (...) {
03376           for (int i = 0; i < new_num_layouts; i++) {
03377             free(tile_table[i]);
03378           }
03379           free(tile_table);
03380           free(itt);
03381           throw;
03382         }
03383 
03384         /* Clean the tile table if it was already set by a previous prop A. */
03385         CleanIndustryTileTable(indsp);
03386         /* Install final layout construction in the industry spec */
03387         indsp->num_table = new_num_layouts;
03388         indsp->table = tile_table;
03389         SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
03390         free(itt);
03391         break;
03392       }
03393 
03394       case 0x0B: // Industry production flags
03395         indsp->life_type = (IndustryLifeType)buf->ReadByte();
03396         break;
03397 
03398       case 0x0C: // Industry closure message
03399         indsp->closure_text = buf->ReadWord();
03400         _string_to_grf_mapping[&indsp->closure_text] = _cur.grffile->grfid;
03401         break;
03402 
03403       case 0x0D: // Production increase message
03404         indsp->production_up_text = buf->ReadWord();
03405         _string_to_grf_mapping[&indsp->production_up_text] = _cur.grffile->grfid;
03406         break;
03407 
03408       case 0x0E: // Production decrease message
03409         indsp->production_down_text = buf->ReadWord();
03410         _string_to_grf_mapping[&indsp->production_down_text] = _cur.grffile->grfid;
03411         break;
03412 
03413       case 0x0F: // Fund cost multiplier
03414         indsp->cost_multiplier = buf->ReadByte();
03415         break;
03416 
03417       case 0x10: // Production cargo types
03418         for (byte j = 0; j < 2; j++) {
03419           indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
03420         }
03421         break;
03422 
03423       case 0x11: // Acceptance cargo types
03424         for (byte j = 0; j < 3; j++) {
03425           indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
03426         }
03427         buf->ReadByte(); // Unnused, eat it up
03428         break;
03429 
03430       case 0x12: // Production multipliers
03431       case 0x13:
03432         indsp->production_rate[prop - 0x12] = buf->ReadByte();
03433         break;
03434 
03435       case 0x14: // Minimal amount of cargo distributed
03436         indsp->minimal_cargo = buf->ReadByte();
03437         break;
03438 
03439       case 0x15: { // Random sound effects
03440         indsp->number_of_sounds = buf->ReadByte();
03441         uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
03442 
03443         try {
03444           for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
03445             sounds[j] = buf->ReadByte();
03446           }
03447         } catch (...) {
03448           free(sounds);
03449           throw;
03450         }
03451 
03452         if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
03453           free(indsp->random_sounds);
03454         }
03455         indsp->random_sounds = sounds;
03456         SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
03457         break;
03458       }
03459 
03460       case 0x16: // Conflicting industry types
03461         for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
03462         break;
03463 
03464       case 0x17: // Probability in random game
03465         indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
03466         break;
03467 
03468       case 0x18: // Probability during gameplay
03469         indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
03470         break;
03471 
03472       case 0x19: // Map colour
03473         indsp->map_colour = buf->ReadByte();
03474         break;
03475 
03476       case 0x1A: // Special industry flags to define special behavior
03477         indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
03478         break;
03479 
03480       case 0x1B: // New industry text ID
03481         indsp->new_industry_text = buf->ReadWord();
03482         _string_to_grf_mapping[&indsp->new_industry_text] = _cur.grffile->grfid;
03483         break;
03484 
03485       case 0x1C: // Input cargo multipliers for the three input cargo types
03486       case 0x1D:
03487       case 0x1E: {
03488           uint32 multiples = buf->ReadDWord();
03489           indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
03490           indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
03491           break;
03492         }
03493 
03494       case 0x1F: // Industry name
03495         indsp->name = buf->ReadWord();
03496         _string_to_grf_mapping[&indsp->name] = _cur.grffile->grfid;
03497         break;
03498 
03499       case 0x20: // Prospecting success chance
03500         indsp->prospecting_chance = buf->ReadDWord();
03501         break;
03502 
03503       case 0x21:   // Callback mask
03504       case 0x22: { // Callback additional mask
03505         byte aflag = buf->ReadByte();
03506         SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
03507         break;
03508       }
03509 
03510       case 0x23: // removal cost multiplier
03511         indsp->removal_cost_multiplier = buf->ReadDWord();
03512         break;
03513 
03514       case 0x24: // name for nearby station
03515         indsp->station_name = buf->ReadWord();
03516         if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur.grffile->grfid;
03517         break;
03518 
03519       default:
03520         ret = CIR_UNKNOWN;
03521         break;
03522     }
03523   }
03524 
03525   return ret;
03526 }
03527 
03533 static void DuplicateTileTable(AirportSpec *as)
03534 {
03535   AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
03536   for (int i = 0; i < as->num_table; i++) {
03537     uint num_tiles = 1;
03538     const AirportTileTable *it = as->table[0];
03539     do {
03540       num_tiles++;
03541     } while ((++it)->ti.x != -0x80);
03542     table_list[i] = MallocT<AirportTileTable>(num_tiles);
03543     MemCpyT(table_list[i], as->table[i], num_tiles);
03544   }
03545   as->table = table_list;
03546   HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
03547   MemCpyT(depot_table, as->depot_table, as->nof_depots);
03548   as->depot_table = depot_table;
03549 }
03550 
03559 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
03560 {
03561   ChangeInfoResult ret = CIR_SUCCESS;
03562 
03563   if (airport + numinfo > NUM_AIRPORTS) {
03564     grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS);
03565     return CIR_INVALID_ID;
03566   }
03567 
03568   /* Allocate industry specs if they haven't been allocated already. */
03569   if (_cur.grffile->airportspec == NULL) {
03570     _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS);
03571   }
03572 
03573   for (int i = 0; i < numinfo; i++) {
03574     AirportSpec *as = _cur.grffile->airportspec[airport + i];
03575 
03576     if (as == NULL && prop != 0x08 && prop != 0x09) {
03577       grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
03578       return CIR_INVALID_ID;
03579     }
03580 
03581     switch (prop) {
03582       case 0x08: { // Modify original airport
03583         byte subs_id = buf->ReadByte();
03584 
03585         if (subs_id == 0xFF) {
03586           /* Instead of defining a new airport, an airport id
03587            * of 0xFF disables the old airport with the current id. */
03588           AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
03589           continue;
03590         } else if (subs_id >= NEW_AIRPORT_OFFSET) {
03591           /* The substitute id must be one of the original airports. */
03592           grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
03593           continue;
03594         }
03595 
03596         AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
03597         /* Allocate space for this airport.
03598          * Only need to do it once. If ever it is called again, it should not
03599          * do anything */
03600         if (*spec == NULL) {
03601           *spec = MallocT<AirportSpec>(1);
03602           as = *spec;
03603 
03604           memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
03605           as->enabled = true;
03606           as->grf_prop.local_id = airport + i;
03607           as->grf_prop.subst_id = subs_id;
03608           as->grf_prop.grffile = _cur.grffile;
03609           /* override the default airport */
03610           _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
03611           /* Create a copy of the original tiletable so it can be freed later. */
03612           DuplicateTileTable(as);
03613         }
03614         break;
03615       }
03616 
03617       case 0x0A: { // Set airport layout
03618         as->num_table = buf->ReadByte(); // Number of layaouts
03619         as->rotation = MallocT<Direction>(as->num_table);
03620         uint32 defsize = buf->ReadDWord();  // Total size of the definition
03621         AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
03622         AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
03623         int size;
03624         const AirportTileTable *copy_from;
03625         try {
03626           for (byte j = 0; j < as->num_table; j++) {
03627             as->rotation[j] = (Direction)buf->ReadByte();
03628             for (int k = 0;; k++) {
03629               att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
03630               att[k].ti.y = buf->ReadByte();
03631 
03632               if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
03633                 /*  Not the same terminator.  The one we are using is rather
03634                  x= -80, y = 0 .  So, adjust it. */
03635                 att[k].ti.x = -0x80;
03636                 att[k].ti.y =  0;
03637                 att[k].gfx  =  0;
03638 
03639                 size = k + 1;
03640                 copy_from = att;
03641                 break;
03642               }
03643 
03644               att[k].gfx = buf->ReadByte();
03645 
03646               if (att[k].gfx == 0xFE) {
03647                 /* Use a new tile from this GRF */
03648                 int local_tile_id = buf->ReadWord();
03649 
03650                 /* Read the ID from the _airporttile_mngr. */
03651                 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
03652 
03653                 if (tempid == INVALID_AIRPORTTILE) {
03654                   grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
03655                 } else {
03656                   /* Declared as been valid, can be used */
03657                   att[k].gfx = tempid;
03658                   size = k + 1;
03659                   copy_from = att;
03660                 }
03661               } else if (att[k].gfx == 0xFF) {
03662                 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
03663                 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
03664               }
03665 
03666               if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
03667                 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
03668                 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
03669               } else {
03670                 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
03671                 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
03672               }
03673             }
03674             tile_table[j] = CallocT<AirportTileTable>(size);
03675             memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03676           }
03677           /* Install final layout construction in the airport spec */
03678           as->table = tile_table;
03679           free(att);
03680         } catch (...) {
03681           for (int i = 0; i < as->num_table; i++) {
03682             free(tile_table[i]);
03683           }
03684           free(tile_table);
03685           free(att);
03686           throw;
03687         }
03688         break;
03689       }
03690 
03691       case 0x0C:
03692         as->min_year = buf->ReadWord();
03693         as->max_year = buf->ReadWord();
03694         if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
03695         break;
03696 
03697       case 0x0D:
03698         as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
03699         break;
03700 
03701       case 0x0E:
03702         as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
03703         break;
03704 
03705       case 0x0F:
03706         as->noise_level = buf->ReadByte();
03707         break;
03708 
03709       case 0x10:
03710         as->name = buf->ReadWord();
03711         _string_to_grf_mapping[&as->name] = _cur.grffile->grfid;
03712         break;
03713 
03714       case 0x11: // Maintenance cost factor
03715         as->maintenance_cost = buf->ReadWord();
03716         break;
03717 
03718       default:
03719         ret = CIR_UNKNOWN;
03720         break;
03721     }
03722   }
03723 
03724   return ret;
03725 }
03726 
03733 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
03734 {
03735   ChangeInfoResult ret = CIR_SUCCESS;
03736 
03737   switch (prop) {
03738     case 0x0B:
03739     case 0x0C:
03740     case 0x0D:
03741     case 0x12:
03742     case 0x14:
03743     case 0x16:
03744     case 0x17:
03745       buf->ReadByte();
03746 
03747     case 0x09:
03748     case 0x0A:
03749     case 0x10:
03750     case 0x11:
03751     case 0x13:
03752     case 0x15:
03753       buf->ReadWord();
03754       break;
03755 
03756     case 0x08:
03757     case 0x0E:
03758     case 0x0F:
03759       buf->ReadDWord();
03760       break;
03761 
03762     default:
03763       ret = CIR_UNKNOWN;
03764       break;
03765   }
03766 
03767   return ret;
03768 }
03769 
03778 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03779 {
03780   ChangeInfoResult ret = CIR_SUCCESS;
03781 
03782   if (id + numinfo > NUM_OBJECTS) {
03783     grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS);
03784     return CIR_INVALID_ID;
03785   }
03786 
03787   /* Allocate object specs if they haven't been allocated already. */
03788   if (_cur.grffile->objectspec == NULL) {
03789     _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS);
03790   }
03791 
03792   for (int i = 0; i < numinfo; i++) {
03793     ObjectSpec *spec = _cur.grffile->objectspec[id + i];
03794 
03795     if (prop != 0x08 && spec == NULL) {
03796       /* If the object property 08 is not yet set, ignore this property */
03797       ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
03798       if (cir > ret) ret = cir;
03799       continue;
03800     }
03801 
03802     switch (prop) {
03803       case 0x08: { // Class ID
03804         ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
03805 
03806         /* Allocate space for this object. */
03807         if (*ospec == NULL) {
03808           *ospec = CallocT<ObjectSpec>(1);
03809           (*ospec)->views = 1; // Default for NewGRFs that don't set it.
03810         }
03811 
03812         /* Swap classid because we read it in BE. */
03813         uint32 classid = buf->ReadDWord();
03814         (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
03815         (*ospec)->enabled = true;
03816         break;
03817       }
03818 
03819       case 0x09: { // Class name
03820         StringID class_name = buf->ReadWord();
03821         ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
03822         objclass->name = class_name;
03823         _string_to_grf_mapping[&objclass->name] = _cur.grffile->grfid;
03824         break;
03825       }
03826 
03827       case 0x0A: // Object name
03828         spec->name = buf->ReadWord();
03829         _string_to_grf_mapping[&spec->name] = _cur.grffile->grfid;
03830         break;
03831 
03832       case 0x0B: // Climate mask
03833         spec->climate = buf->ReadByte();
03834         break;
03835 
03836       case 0x0C: // Size
03837         spec->size = buf->ReadByte();
03838         break;
03839 
03840       case 0x0D: // Build cost multipler
03841         spec->build_cost_multiplier = buf->ReadByte();
03842         spec->clear_cost_multiplier = spec->build_cost_multiplier;
03843         break;
03844 
03845       case 0x0E: // Introduction date
03846         spec->introduction_date = buf->ReadDWord();
03847         break;
03848 
03849       case 0x0F: // End of life
03850         spec->end_of_life_date = buf->ReadDWord();
03851         break;
03852 
03853       case 0x10: // Flags
03854         spec->flags = (ObjectFlags)buf->ReadWord();
03855         _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
03856         break;
03857 
03858       case 0x11: // Animation info
03859         spec->animation.frames = buf->ReadByte();
03860         spec->animation.status = buf->ReadByte();
03861         break;
03862 
03863       case 0x12: // Animation speed
03864         spec->animation.speed = buf->ReadByte();
03865         break;
03866 
03867       case 0x13: // Animation triggers
03868         spec->animation.triggers = buf->ReadWord();
03869         break;
03870 
03871       case 0x14: // Removal cost multiplier
03872         spec->clear_cost_multiplier = buf->ReadByte();
03873         break;
03874 
03875       case 0x15: // Callback mask
03876         spec->callback_mask = buf->ReadWord();
03877         break;
03878 
03879       case 0x16: // Building height
03880         spec->height = buf->ReadByte();
03881         break;
03882 
03883       case 0x17: // Views
03884         spec->views = buf->ReadByte();
03885         if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
03886           grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
03887           spec->views = 1;
03888         }
03889         break;
03890 
03891       default:
03892         ret = CIR_UNKNOWN;
03893         break;
03894     }
03895   }
03896 
03897   return ret;
03898 }
03899 
03908 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03909 {
03910   ChangeInfoResult ret = CIR_SUCCESS;
03911 
03912   extern RailtypeInfo _railtypes[RAILTYPE_END];
03913 
03914   if (id + numinfo > RAILTYPE_END) {
03915     grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03916     return CIR_INVALID_ID;
03917   }
03918 
03919   for (int i = 0; i < numinfo; i++) {
03920     RailType rt = _cur.grffile->railtype_map[id + i];
03921     if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
03922 
03923     RailtypeInfo *rti = &_railtypes[rt];
03924 
03925     switch (prop) {
03926       case 0x08: // Label of rail type
03927         /* Skipped here as this is loaded during reservation stage. */
03928         buf->ReadDWord();
03929         break;
03930 
03931       case 0x09: // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
03932         rti->strings.toolbar_caption = buf->ReadWord();
03933         _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur.grffile->grfid;
03934         if (_cur.grffile->grf_version < 8) {
03935           rti->strings.name = rti->strings.toolbar_caption;
03936           _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
03937         }
03938         break;
03939 
03940       case 0x0A: // Menu text of railtype
03941         rti->strings.menu_text = buf->ReadWord();
03942         _string_to_grf_mapping[&rti->strings.menu_text] = _cur.grffile->grfid;
03943         break;
03944 
03945       case 0x0B: // Build window caption
03946         rti->strings.build_caption = buf->ReadWord();
03947         _string_to_grf_mapping[&rti->strings.build_caption] = _cur.grffile->grfid;
03948         break;
03949 
03950       case 0x0C: // Autoreplace text
03951         rti->strings.replace_text = buf->ReadWord();
03952         _string_to_grf_mapping[&rti->strings.replace_text] = _cur.grffile->grfid;
03953         break;
03954 
03955       case 0x0D: // New locomotive text
03956         rti->strings.new_loco = buf->ReadWord();
03957         _string_to_grf_mapping[&rti->strings.new_loco] = _cur.grffile->grfid;
03958         break;
03959 
03960       case 0x0E: // Compatible railtype list
03961       case 0x0F: // Powered railtype list
03962       case 0x18: // Railtype list required for date introduction
03963       case 0x19: // Introduced railtype list
03964       {
03965         /* Rail type compatibility bits are added to the existing bits
03966          * to allow multiple GRFs to modify compatibility with the
03967          * default rail types. */
03968         int n = buf->ReadByte();
03969         for (int j = 0; j != n; j++) {
03970           RailTypeLabel label = buf->ReadDWord();
03971           RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
03972           if (rt != INVALID_RAILTYPE) {
03973             switch (prop) {
03974               case 0x0E: SetBit(rti->compatible_railtypes, rt);            break;
03975               case 0x0F: SetBit(rti->powered_railtypes, rt);               break;
03976               case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
03977               case 0x19: SetBit(rti->introduces_railtypes, rt);            break;
03978             }
03979           }
03980         }
03981         break;
03982       }
03983 
03984       case 0x10: // Rail Type flags
03985         rti->flags = (RailTypeFlags)buf->ReadByte();
03986         break;
03987 
03988       case 0x11: // Curve speed advantage
03989         rti->curve_speed = buf->ReadByte();
03990         break;
03991 
03992       case 0x12: // Station graphic
03993         rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
03994         break;
03995 
03996       case 0x13: // Construction cost factor
03997         rti->cost_multiplier = buf->ReadWord();
03998         break;
03999 
04000       case 0x14: // Speed limit
04001         rti->max_speed = buf->ReadWord();
04002         break;
04003 
04004       case 0x15: // Acceleration model
04005         rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
04006         break;
04007 
04008       case 0x16: // Map colour
04009         rti->map_colour = buf->ReadByte();
04010         break;
04011 
04012       case 0x17: // Introduction date
04013         rti->introduction_date = buf->ReadDWord();
04014         break;
04015 
04016       case 0x1A: // Sort order
04017         rti->sorting_order = buf->ReadByte();
04018         break;
04019 
04020       case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
04021         rti->strings.name = buf->ReadWord();
04022         _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
04023         break;
04024 
04025       case 0x1C: // Maintenance cost factor
04026         rti->maintenance_multiplier = buf->ReadWord();
04027         break;
04028 
04029       case 0x1D: // Alternate rail type label list
04030         /* Skipped here as this is loaded during reservation stage. */
04031         for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
04032         break;
04033 
04034       default:
04035         ret = CIR_UNKNOWN;
04036         break;
04037     }
04038   }
04039 
04040   return ret;
04041 }
04042 
04043 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
04044 {
04045   ChangeInfoResult ret = CIR_SUCCESS;
04046 
04047   extern RailtypeInfo _railtypes[RAILTYPE_END];
04048 
04049   if (id + numinfo > RAILTYPE_END) {
04050     grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
04051     return CIR_INVALID_ID;
04052   }
04053 
04054   for (int i = 0; i < numinfo; i++) {
04055     switch (prop) {
04056       case 0x08: // Label of rail type
04057       {
04058         RailTypeLabel rtl = buf->ReadDWord();
04059         rtl = BSWAP32(rtl);
04060 
04061         RailType rt = GetRailTypeByLabel(rtl, false);
04062         if (rt == INVALID_RAILTYPE) {
04063           /* Set up new rail type */
04064           rt = AllocateRailType(rtl);
04065         }
04066 
04067         _cur.grffile->railtype_map[id + i] = rt;
04068         break;
04069       }
04070 
04071       case 0x09: // Toolbar caption of railtype
04072       case 0x0A: // Menu text
04073       case 0x0B: // Build window caption
04074       case 0x0C: // Autoreplace text
04075       case 0x0D: // New loco
04076       case 0x13: // Construction cost
04077       case 0x14: // Speed limit
04078       case 0x1B: // Name of railtype
04079       case 0x1C: // Maintenance cost factor
04080         buf->ReadWord();
04081         break;
04082 
04083       case 0x1D: // Alternate rail type label list
04084         if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
04085           int n = buf->ReadByte();
04086           for (int j = 0; j != n; j++) {
04087             *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
04088           }
04089           break;
04090         }
04091         grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
04092         /* FALL THROUGH */
04093 
04094       case 0x0E: // Compatible railtype list
04095       case 0x0F: // Powered railtype list
04096       case 0x18: // Railtype list required for date introduction
04097       case 0x19: // Introduced railtype list
04098         for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
04099         break;
04100 
04101       case 0x10: // Rail Type flags
04102       case 0x11: // Curve speed advantage
04103       case 0x12: // Station graphic
04104       case 0x15: // Acceleration model
04105       case 0x16: // Map colour
04106       case 0x1A: // Sort order
04107         buf->ReadByte();
04108         break;
04109 
04110       case 0x17: // Introduction date
04111         buf->ReadDWord();
04112         break;
04113 
04114       default:
04115         ret = CIR_UNKNOWN;
04116         break;
04117     }
04118   }
04119 
04120   return ret;
04121 }
04122 
04123 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
04124 {
04125   ChangeInfoResult ret = CIR_SUCCESS;
04126 
04127   if (airtid + numinfo > NUM_AIRPORTTILES) {
04128     grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
04129     return CIR_INVALID_ID;
04130   }
04131 
04132   /* Allocate airport tile specs if they haven't been allocated already. */
04133   if (_cur.grffile->airtspec == NULL) {
04134     _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
04135   }
04136 
04137   for (int i = 0; i < numinfo; i++) {
04138     AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
04139 
04140     if (prop != 0x08 && tsp == NULL) {
04141       grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
04142       return CIR_INVALID_ID;
04143     }
04144 
04145     switch (prop) {
04146       case 0x08: { // Substitute airport tile type
04147         AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
04148         byte subs_id = buf->ReadByte();
04149 
04150         if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
04151           /* The substitute id must be one of the original airport tiles. */
04152           grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
04153           continue;
04154         }
04155 
04156         /* Allocate space for this airport tile. */
04157         if (*tilespec == NULL) {
04158           *tilespec = CallocT<AirportTileSpec>(1);
04159           tsp = *tilespec;
04160 
04161           memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
04162           tsp->enabled = true;
04163 
04164           tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
04165 
04166           tsp->grf_prop.local_id = airtid + i;
04167           tsp->grf_prop.subst_id = subs_id;
04168           tsp->grf_prop.grffile = _cur.grffile;
04169           _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
04170         }
04171         break;
04172       }
04173 
04174       case 0x09: { // Airport tile override
04175         byte override = buf->ReadByte();
04176 
04177         /* The airport tile being overridden must be an original airport tile. */
04178         if (override >= NEW_AIRPORTTILE_OFFSET) {
04179           grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
04180           continue;
04181         }
04182 
04183         _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
04184         break;
04185       }
04186 
04187       case 0x0E: // Callback mask
04188         tsp->callback_mask = buf->ReadByte();
04189         break;
04190 
04191       case 0x0F: // Animation information
04192         tsp->animation.frames = buf->ReadByte();
04193         tsp->animation.status = buf->ReadByte();
04194         break;
04195 
04196       case 0x10: // Animation speed
04197         tsp->animation.speed = buf->ReadByte();
04198         break;
04199 
04200       case 0x11: // Animation triggers
04201         tsp->animation.triggers = buf->ReadByte();
04202         break;
04203 
04204       default:
04205         ret = CIR_UNKNOWN;
04206         break;
04207     }
04208   }
04209 
04210   return ret;
04211 }
04212 
04213 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
04214 {
04215   switch (cir) {
04216     default: NOT_REACHED();
04217 
04218     case CIR_DISABLED:
04219       /* Error has already been printed; just stop parsing */
04220       return true;
04221 
04222     case CIR_SUCCESS:
04223       return false;
04224 
04225     case CIR_UNHANDLED:
04226       grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
04227       return false;
04228 
04229     case CIR_UNKNOWN:
04230       grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
04231       /* FALL THROUGH */
04232 
04233     case CIR_INVALID_ID: {
04234       /* No debug message for an invalid ID, as it has already been output */
04235       GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
04236       if (cir != CIR_INVALID_ID) error->param_value[1] = property;
04237       return true;
04238     }
04239   }
04240 }
04241 
04242 /* Action 0x00 */
04243 static void FeatureChangeInfo(ByteReader *buf)
04244 {
04245   /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
04246    *
04247    * B feature
04248    * B num-props     how many properties to change per vehicle/station
04249    * B num-info      how many vehicles/stations to change
04250    * E id            ID of first vehicle/station to change, if num-info is
04251    *                 greater than one, this one and the following
04252    *                 vehicles/stations will be changed
04253    * B property      what property to change, depends on the feature
04254    * V new-info      new bytes of info (variable size; depends on properties) */
04255 
04256   static const VCI_Handler handler[] = {
04257     /* GSF_TRAINS */        RailVehicleChangeInfo,
04258     /* GSF_ROADVEHICLES */  RoadVehicleChangeInfo,
04259     /* GSF_SHIPS */         ShipVehicleChangeInfo,
04260     /* GSF_AIRCRAFT */      AircraftVehicleChangeInfo,
04261     /* GSF_STATIONS */      StationChangeInfo,
04262     /* GSF_CANALS */        CanalChangeInfo,
04263     /* GSF_BRIDGES */       BridgeChangeInfo,
04264     /* GSF_HOUSES */        TownHouseChangeInfo,
04265     /* GSF_GLOBALVAR */     GlobalVarChangeInfo,
04266     /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
04267     /* GSF_INDUSTRIES */    IndustriesChangeInfo,
04268     /* GSF_CARGOES */       NULL, // Cargo is handled during reservation
04269     /* GSF_SOUNDFX */       SoundEffectChangeInfo,
04270     /* GSF_AIRPORTS */      AirportChangeInfo,
04271     /* GSF_SIGNALS */       NULL,
04272     /* GSF_OBJECTS */       ObjectChangeInfo,
04273     /* GSF_RAILTYPES */     RailTypeChangeInfo,
04274     /* GSF_AIRPORTTILES */  AirportTilesChangeInfo,
04275   };
04276 
04277   uint8 feature  = buf->ReadByte();
04278   uint8 numprops = buf->ReadByte();
04279   uint numinfo  = buf->ReadByte();
04280   uint engine   = buf->ReadExtendedByte();
04281 
04282   grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
04283                  feature, numprops, engine, numinfo);
04284 
04285   if (feature >= lengthof(handler) || handler[feature] == NULL) {
04286     if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
04287     return;
04288   }
04289 
04290   /* Mark the feature as used by the grf */
04291   SetBit(_cur.grffile->grf_features, feature);
04292 
04293   while (numprops-- && buf->HasData()) {
04294     uint8 prop = buf->ReadByte();
04295 
04296     ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
04297     if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
04298   }
04299 }
04300 
04301 /* Action 0x00 (GLS_SAFETYSCAN) */
04302 static void SafeChangeInfo(ByteReader *buf)
04303 {
04304   uint8 feature  = buf->ReadByte();
04305   uint8 numprops = buf->ReadByte();
04306   uint numinfo = buf->ReadByte();
04307   buf->ReadExtendedByte(); // id
04308 
04309   if (feature == GSF_BRIDGES && numprops == 1) {
04310     uint8 prop = buf->ReadByte();
04311     /* Bridge property 0x0D is redefinition of sprite layout tables, which
04312      * is considered safe. */
04313     if (prop == 0x0D) return;
04314   } else if (feature == GSF_GLOBALVAR && numprops == 1) {
04315     uint8 prop = buf->ReadByte();
04316     /* Engine ID Mappings are safe, if the source is static */
04317     if (prop == 0x11) {
04318       bool is_safe = true;
04319       for (uint i = 0; i < numinfo; i++) {
04320         uint32 s = buf->ReadDWord();
04321         buf->ReadDWord(); // dest
04322         const GRFConfig *grfconfig = GetGRFConfig(s);
04323         if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
04324           is_safe = false;
04325           break;
04326         }
04327       }
04328       if (is_safe) return;
04329     }
04330   }
04331 
04332   SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
04333 
04334   /* Skip remainder of GRF */
04335   _cur.skip_sprites = -1;
04336 }
04337 
04338 /* Action 0x00 (GLS_RESERVE) */
04339 static void ReserveChangeInfo(ByteReader *buf)
04340 {
04341   uint8 feature  = buf->ReadByte();
04342 
04343   if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
04344 
04345   uint8 numprops = buf->ReadByte();
04346   uint8 numinfo  = buf->ReadByte();
04347   uint8 index    = buf->ReadExtendedByte();
04348 
04349   while (numprops-- && buf->HasData()) {
04350     uint8 prop = buf->ReadByte();
04351     ChangeInfoResult cir = CIR_SUCCESS;
04352 
04353     switch (feature) {
04354       default: NOT_REACHED();
04355       case GSF_CARGOES:
04356         cir = CargoChangeInfo(index, numinfo, prop, buf);
04357         break;
04358 
04359       case GSF_GLOBALVAR:
04360         cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
04361         break;
04362 
04363       case GSF_RAILTYPES:
04364         cir = RailTypeReserveInfo(index, numinfo, prop, buf);
04365         break;
04366     }
04367 
04368     if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
04369   }
04370 }
04371 
04372 /* Action 0x01 */
04373 static void NewSpriteSet(ByteReader *buf)
04374 {
04375   /* Basic format:    <01> <feature> <num-sets> <num-ent>
04376    * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
04377    *
04378    * B feature       feature to define sprites for
04379    *                 0, 1, 2, 3: veh-type, 4: train stations
04380    * E first-set     first sprite set to define
04381    * B num-sets      number of sprite sets (extended byte in extended format)
04382    * E num-ent       how many entries per sprite set
04383    *                 For vehicles, this is the number of different
04384    *                         vehicle directions in each sprite set
04385    *                         Set num-dirs=8, unless your sprites are symmetric.
04386    *                         In that case, use num-dirs=4.
04387    */
04388 
04389   uint8  feature   = buf->ReadByte();
04390   uint16 num_sets  = buf->ReadByte();
04391   uint16 first_set = 0;
04392 
04393   if (num_sets == 0 && buf->HasData(3)) {
04394     /* Extended Action1 format.
04395      * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
04396     first_set = buf->ReadExtendedByte();
04397     num_sets = buf->ReadExtendedByte();
04398   }
04399   uint16 num_ents = buf->ReadExtendedByte();
04400 
04401   _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
04402 
04403   grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
04404     _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
04405   );
04406 
04407   for (int i = 0; i < num_sets * num_ents; i++) {
04408     _cur.nfo_line++;
04409     LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
04410   }
04411 }
04412 
04413 /* Action 0x01 (SKIP) */
04414 static void SkipAct1(ByteReader *buf)
04415 {
04416   buf->ReadByte();
04417   uint16 num_sets  = buf->ReadByte();
04418 
04419   if (num_sets == 0 && buf->HasData(3)) {
04420     /* Extended Action1 format.
04421      * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
04422     buf->ReadExtendedByte(); // first_set
04423     num_sets = buf->ReadExtendedByte();
04424   }
04425   uint16 num_ents = buf->ReadExtendedByte();
04426 
04427   _cur.skip_sprites = num_sets * num_ents;
04428 
04429   grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
04430 }
04431 
04432 /* Helper function to either create a callback or link to a previously
04433  * defined spritegroup. */
04434 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
04435 {
04436   if (HasBit(groupid, 15)) {
04437     assert(CallbackResultSpriteGroup::CanAllocateItem());
04438     return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
04439   }
04440 
04441   if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04442     grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
04443     return NULL;
04444   }
04445 
04446   return _cur.spritegroups[groupid];
04447 }
04448 
04457 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
04458 {
04459   if (HasBit(spriteid, 15)) {
04460     assert(CallbackResultSpriteGroup::CanAllocateItem());
04461     return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
04462   }
04463 
04464   if (!_cur.IsValidSpriteSet(feature, spriteid)) {
04465     grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
04466     return NULL;
04467   }
04468 
04469   SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
04470   uint num_sprites = _cur.GetNumEnts(feature, spriteid);
04471 
04472   /* Ensure that the sprites are loeded */
04473   assert(spriteset_start + num_sprites <= _cur.spriteid);
04474 
04475   assert(ResultSpriteGroup::CanAllocateItem());
04476   return new ResultSpriteGroup(spriteset_start, num_sprites);
04477 }
04478 
04479 /* Action 0x02 */
04480 static void NewSpriteGroup(ByteReader *buf)
04481 {
04482   /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
04483    *
04484    * B feature       see action 1
04485    * B set-id        ID of this particular definition
04486    * B type/num-entries
04487    *                 if 80 or greater, this is a randomized or variational
04488    *                 list definition, see below
04489    *                 otherwise it specifies a number of entries, the exact
04490    *                 meaning depends on the feature
04491    * V feature-specific-data (huge mess, don't even look it up --pasky) */
04492   SpriteGroup *act_group = NULL;
04493 
04494   uint8 feature = buf->ReadByte();
04495   uint8 setid   = buf->ReadByte();
04496   uint8 type    = buf->ReadByte();
04497 
04498   /* Sprite Groups are created here but they are allocated from a pool, so
04499    * we do not need to delete anything if there is an exception from the
04500    * ByteReader. */
04501 
04502   switch (type) {
04503     /* Deterministic Sprite Group */
04504     case 0x81: // Self scope, byte
04505     case 0x82: // Parent scope, byte
04506     case 0x85: // Self scope, word
04507     case 0x86: // Parent scope, word
04508     case 0x89: // Self scope, dword
04509     case 0x8A: // Parent scope, dword
04510     {
04511       byte varadjust;
04512       byte varsize;
04513 
04514       assert(DeterministicSpriteGroup::CanAllocateItem());
04515       DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
04516       act_group = group;
04517       group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04518 
04519       switch (GB(type, 2, 2)) {
04520         default: NOT_REACHED();
04521         case 0: group->size = DSG_SIZE_BYTE;  varsize = 1; break;
04522         case 1: group->size = DSG_SIZE_WORD;  varsize = 2; break;
04523         case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
04524       }
04525 
04526       static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
04527       adjusts.Clear();
04528 
04529       /* Loop through the var adjusts. Unfortunately we don't know how many we have
04530        * from the outset, so we shall have to keep reallocing. */
04531       do {
04532         DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
04533 
04534         /* The first var adjust doesn't have an operation specified, so we set it to add. */
04535         adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
04536         adjust->variable  = buf->ReadByte();
04537         if (adjust->variable == 0x7E) {
04538           /* Link subroutine group */
04539           adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
04540         } else {
04541           adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
04542         }
04543 
04544         varadjust = buf->ReadByte();
04545         adjust->shift_num = GB(varadjust, 0, 5);
04546         adjust->type      = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
04547         adjust->and_mask  = buf->ReadVarSize(varsize);
04548 
04549         if (adjust->type != DSGA_TYPE_NONE) {
04550           adjust->add_val    = buf->ReadVarSize(varsize);
04551           adjust->divmod_val = buf->ReadVarSize(varsize);
04552         } else {
04553           adjust->add_val    = 0;
04554           adjust->divmod_val = 0;
04555         }
04556 
04557         /* Continue reading var adjusts while bit 5 is set. */
04558       } while (HasBit(varadjust, 5));
04559 
04560       group->num_adjusts = adjusts.Length();
04561       group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
04562       MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
04563 
04564       group->num_ranges = buf->ReadByte();
04565       if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
04566 
04567       for (uint i = 0; i < group->num_ranges; i++) {
04568         group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04569         group->ranges[i].low   = buf->ReadVarSize(varsize);
04570         group->ranges[i].high  = buf->ReadVarSize(varsize);
04571       }
04572 
04573       group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04574       break;
04575     }
04576 
04577     /* Randomized Sprite Group */
04578     case 0x80: // Self scope
04579     case 0x83: // Parent scope
04580     case 0x84: // Relative scope
04581     {
04582       assert(RandomizedSpriteGroup::CanAllocateItem());
04583       RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
04584       act_group = group;
04585       group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04586 
04587       if (HasBit(type, 2)) {
04588         if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
04589         group->count = buf->ReadByte();
04590       }
04591 
04592       uint8 triggers = buf->ReadByte();
04593       group->triggers       = GB(triggers, 0, 7);
04594       group->cmp_mode       = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
04595       group->lowest_randbit = buf->ReadByte();
04596       group->num_groups     = buf->ReadByte();
04597       group->groups = CallocT<const SpriteGroup*>(group->num_groups);
04598 
04599       for (uint i = 0; i < group->num_groups; i++) {
04600         group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
04601       }
04602 
04603       break;
04604     }
04605 
04606     /* Neither a variable or randomized sprite group... must be a real group */
04607     default:
04608     {
04609       switch (feature) {
04610         case GSF_TRAINS:
04611         case GSF_ROADVEHICLES:
04612         case GSF_SHIPS:
04613         case GSF_AIRCRAFT:
04614         case GSF_STATIONS:
04615         case GSF_CANALS:
04616         case GSF_CARGOES:
04617         case GSF_AIRPORTS:
04618         case GSF_RAILTYPES:
04619         {
04620           byte num_loaded  = type;
04621           byte num_loading = buf->ReadByte();
04622 
04623           if (!_cur.HasValidSpriteSets(feature)) {
04624             grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
04625             return;
04626           }
04627 
04628           assert(RealSpriteGroup::CanAllocateItem());
04629           RealSpriteGroup *group = new RealSpriteGroup();
04630           act_group = group;
04631 
04632           group->num_loaded  = num_loaded;
04633           group->num_loading = num_loading;
04634           if (num_loaded  > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
04635           if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
04636 
04637           grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
04638               setid, num_loaded, num_loading);
04639 
04640           for (uint i = 0; i < num_loaded; i++) {
04641             uint16 spriteid = buf->ReadWord();
04642             group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04643             grfmsg(8, "NewSpriteGroup: + rg->loaded[%i]  = subset %u", i, spriteid);
04644           }
04645 
04646           for (uint i = 0; i < num_loading; i++) {
04647             uint16 spriteid = buf->ReadWord();
04648             group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04649             grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
04650           }
04651 
04652           break;
04653         }
04654 
04655         case GSF_HOUSES:
04656         case GSF_AIRPORTTILES:
04657         case GSF_OBJECTS:
04658         case GSF_INDUSTRYTILES: {
04659           byte num_building_sprites = max((uint8)1, type);
04660 
04661           assert(TileLayoutSpriteGroup::CanAllocateItem());
04662           TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
04663           act_group = group;
04664 
04665           /* On error, bail out immediately. Temporary GRF data was already freed */
04666           if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
04667           break;
04668         }
04669 
04670         case GSF_INDUSTRIES: {
04671           if (type > 1) {
04672             grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
04673             break;
04674           }
04675 
04676           assert(IndustryProductionSpriteGroup::CanAllocateItem());
04677           IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04678           act_group = group;
04679           group->version = type;
04680           if (type == 0) {
04681             for (uint i = 0; i < 3; i++) {
04682               group->subtract_input[i] = (int16)buf->ReadWord(); // signed
04683             }
04684             for (uint i = 0; i < 2; i++) {
04685               group->add_output[i] = buf->ReadWord(); // unsigned
04686             }
04687             group->again = buf->ReadByte();
04688           } else {
04689             for (uint i = 0; i < 3; i++) {
04690               group->subtract_input[i] = buf->ReadByte();
04691             }
04692             for (uint i = 0; i < 2; i++) {
04693               group->add_output[i] = buf->ReadByte();
04694             }
04695             group->again = buf->ReadByte();
04696           }
04697           break;
04698         }
04699 
04700         /* Loading of Tile Layout and Production Callback groups would happen here */
04701         default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04702       }
04703     }
04704   }
04705 
04706   _cur.spritegroups[setid] = act_group;
04707 }
04708 
04709 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04710 {
04711   if (feature == GSF_OBJECTS) {
04712     switch (ctype) {
04713       case 0:    return 0;
04714       case 0xFF: return CT_PURCHASE_OBJECT;
04715       default:
04716         grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04717         return CT_INVALID;
04718     }
04719   }
04720   /* Special cargo types for purchase list and stations */
04721   if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04722   if (ctype == 0xFF) return CT_PURCHASE;
04723 
04724   if (_cur.grffile->cargo_list.Length() == 0) {
04725     /* No cargo table, so use bitnum values */
04726     if (ctype >= 32) {
04727       grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04728       return CT_INVALID;
04729     }
04730 
04731     const CargoSpec *cs;
04732     FOR_ALL_CARGOSPECS(cs) {
04733       if (cs->bitnum == ctype) {
04734         grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04735         return cs->Index();
04736       }
04737     }
04738 
04739     grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04740     return CT_INVALID;
04741   }
04742 
04743   /* Check if the cargo type is out of bounds of the cargo translation table */
04744   if (ctype >= _cur.grffile->cargo_list.Length()) {
04745     grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
04746     return CT_INVALID;
04747   }
04748 
04749   /* Look up the cargo label from the translation table */
04750   CargoLabel cl = _cur.grffile->cargo_list[ctype];
04751   if (cl == 0) {
04752     grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04753     return CT_INVALID;
04754   }
04755 
04756   ctype = GetCargoIDByLabel(cl);
04757   if (ctype == CT_INVALID) {
04758     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));
04759     return CT_INVALID;
04760   }
04761 
04762   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);
04763   return ctype;
04764 }
04765 
04766 
04767 static bool IsValidGroupID(uint16 groupid, const char *function)
04768 {
04769   if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04770     grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
04771     return false;
04772   }
04773 
04774   return true;
04775 }
04776 
04777 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04778 {
04779   static EngineID *last_engines;
04780   static uint last_engines_count;
04781   bool wagover = false;
04782 
04783   /* Test for 'wagon override' flag */
04784   if (HasBit(idcount, 7)) {
04785     wagover = true;
04786     /* Strip off the flag */
04787     idcount = GB(idcount, 0, 7);
04788 
04789     if (last_engines_count == 0) {
04790       grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04791       return;
04792     }
04793 
04794     grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04795         last_engines_count, idcount);
04796   } else {
04797     if (last_engines_count != idcount) {
04798       last_engines = ReallocT(last_engines, idcount);
04799       last_engines_count = idcount;
04800     }
04801   }
04802 
04803   EngineID *engines = AllocaM(EngineID, idcount);
04804   for (uint i = 0; i < idcount; i++) {
04805     Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
04806     if (e == NULL) {
04807       /* No engine could be allocated?!? Deal with it. Okay,
04808        * this might look bad. Also make sure this NewGRF
04809        * gets disabled, as a half loaded one is bad. */
04810       HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04811       return;
04812     }
04813 
04814     engines[i] = e->index;
04815     if (!wagover) last_engines[i] = engines[i];
04816   }
04817 
04818   uint8 cidcount = buf->ReadByte();
04819   for (uint c = 0; c < cidcount; c++) {
04820     uint8 ctype = buf->ReadByte();
04821     uint16 groupid = buf->ReadWord();
04822     if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04823 
04824     grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04825 
04826     ctype = TranslateCargo(feature, ctype);
04827     if (ctype == CT_INVALID) continue;
04828 
04829     for (uint i = 0; i < idcount; i++) {
04830       EngineID engine = engines[i];
04831 
04832       grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04833 
04834       if (wagover) {
04835         SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
04836       } else {
04837         SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
04838       }
04839     }
04840   }
04841 
04842   uint16 groupid = buf->ReadWord();
04843   if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04844 
04845   grfmsg(8, "-- Default group id 0x%04X", groupid);
04846 
04847   for (uint i = 0; i < idcount; i++) {
04848     EngineID engine = engines[i];
04849 
04850     if (wagover) {
04851       SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
04852     } else {
04853       SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
04854       SetEngineGRF(engine, _cur.grffile);
04855     }
04856   }
04857 }
04858 
04859 
04860 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04861 {
04862   CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04863   for (uint i = 0; i < idcount; i++) {
04864     cfs[i] = (CanalFeature)buf->ReadByte();
04865   }
04866 
04867   uint8 cidcount = buf->ReadByte();
04868   buf->Skip(cidcount * 3);
04869 
04870   uint16 groupid = buf->ReadWord();
04871   if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04872 
04873   for (uint i = 0; i < idcount; i++) {
04874     CanalFeature cf = cfs[i];
04875 
04876     if (cf >= CF_END) {
04877       grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04878       continue;
04879     }
04880 
04881     _water_feature[cf].grffile = _cur.grffile;
04882     _water_feature[cf].group = _cur.spritegroups[groupid];
04883   }
04884 }
04885 
04886 
04887 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04888 {
04889   uint8 *stations = AllocaM(uint8, idcount);
04890   for (uint i = 0; i < idcount; i++) {
04891     stations[i] = buf->ReadByte();
04892   }
04893 
04894   uint8 cidcount = buf->ReadByte();
04895   for (uint c = 0; c < cidcount; c++) {
04896     uint8 ctype = buf->ReadByte();
04897     uint16 groupid = buf->ReadWord();
04898     if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04899 
04900     ctype = TranslateCargo(GSF_STATIONS, ctype);
04901     if (ctype == CT_INVALID) continue;
04902 
04903     for (uint i = 0; i < idcount; i++) {
04904       StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04905 
04906       if (statspec == NULL) {
04907         grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04908         continue;
04909       }
04910 
04911       statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
04912     }
04913   }
04914 
04915   uint16 groupid = buf->ReadWord();
04916   if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04917 
04918   for (uint i = 0; i < idcount; i++) {
04919     StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04920 
04921     if (statspec == NULL) {
04922       grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04923       continue;
04924     }
04925 
04926     if (statspec->grf_prop.grffile != NULL) {
04927       grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04928       continue;
04929     }
04930 
04931     statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
04932     statspec->grf_prop.grffile = _cur.grffile;
04933     statspec->grf_prop.local_id = stations[i];
04934     StationClass::Assign(statspec);
04935   }
04936 }
04937 
04938 
04939 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04940 {
04941   uint8 *houses = AllocaM(uint8, idcount);
04942   for (uint i = 0; i < idcount; i++) {
04943     houses[i] = buf->ReadByte();
04944   }
04945 
04946   /* Skip the cargo type section, we only care about the default group */
04947   uint8 cidcount = buf->ReadByte();
04948   buf->Skip(cidcount * 3);
04949 
04950   uint16 groupid = buf->ReadWord();
04951   if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04952 
04953   if (_cur.grffile->housespec == NULL) {
04954     grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04955     return;
04956   }
04957 
04958   for (uint i = 0; i < idcount; i++) {
04959     HouseSpec *hs = _cur.grffile->housespec[houses[i]];
04960 
04961     if (hs == NULL) {
04962       grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04963       continue;
04964     }
04965 
04966     hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04967   }
04968 }
04969 
04970 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04971 {
04972   uint8 *industries = AllocaM(uint8, idcount);
04973   for (uint i = 0; i < idcount; i++) {
04974     industries[i] = buf->ReadByte();
04975   }
04976 
04977   /* Skip the cargo type section, we only care about the default group */
04978   uint8 cidcount = buf->ReadByte();
04979   buf->Skip(cidcount * 3);
04980 
04981   uint16 groupid = buf->ReadWord();
04982   if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04983 
04984   if (_cur.grffile->industryspec == NULL) {
04985     grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04986     return;
04987   }
04988 
04989   for (uint i = 0; i < idcount; i++) {
04990     IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
04991 
04992     if (indsp == NULL) {
04993       grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04994       continue;
04995     }
04996 
04997     indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04998   }
04999 }
05000 
05001 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
05002 {
05003   uint8 *indtiles = AllocaM(uint8, idcount);
05004   for (uint i = 0; i < idcount; i++) {
05005     indtiles[i] = buf->ReadByte();
05006   }
05007 
05008   /* Skip the cargo type section, we only care about the default group */
05009   uint8 cidcount = buf->ReadByte();
05010   buf->Skip(cidcount * 3);
05011 
05012   uint16 groupid = buf->ReadWord();
05013   if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
05014 
05015   if (_cur.grffile->indtspec == NULL) {
05016     grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
05017     return;
05018   }
05019 
05020   for (uint i = 0; i < idcount; i++) {
05021     IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
05022 
05023     if (indtsp == NULL) {
05024       grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
05025       continue;
05026     }
05027 
05028     indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05029   }
05030 }
05031 
05032 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
05033 {
05034   CargoID *cargoes = AllocaM(CargoID, idcount);
05035   for (uint i = 0; i < idcount; i++) {
05036     cargoes[i] = buf->ReadByte();
05037   }
05038 
05039   /* Skip the cargo type section, we only care about the default group */
05040   uint8 cidcount = buf->ReadByte();
05041   buf->Skip(cidcount * 3);
05042 
05043   uint16 groupid = buf->ReadWord();
05044   if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
05045 
05046   for (uint i = 0; i < idcount; i++) {
05047     CargoID cid = cargoes[i];
05048 
05049     if (cid >= NUM_CARGO) {
05050       grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
05051       continue;
05052     }
05053 
05054     CargoSpec *cs = CargoSpec::Get(cid);
05055     cs->grffile = _cur.grffile;
05056     cs->group = _cur.spritegroups[groupid];
05057   }
05058 }
05059 
05060 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
05061 {
05062   if (_cur.grffile->objectspec == NULL) {
05063     grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
05064     return;
05065   }
05066 
05067   uint8 *objects = AllocaM(uint8, idcount);
05068   for (uint i = 0; i < idcount; i++) {
05069     objects[i] = buf->ReadByte();
05070   }
05071 
05072   uint8 cidcount = buf->ReadByte();
05073   for (uint c = 0; c < cidcount; c++) {
05074     uint8 ctype = buf->ReadByte();
05075     uint16 groupid = buf->ReadWord();
05076     if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
05077 
05078     ctype = TranslateCargo(GSF_OBJECTS, ctype);
05079     if (ctype == CT_INVALID) continue;
05080 
05081     for (uint i = 0; i < idcount; i++) {
05082       ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05083 
05084       if (spec == NULL) {
05085         grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05086         continue;
05087       }
05088 
05089       spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
05090     }
05091   }
05092 
05093   uint16 groupid = buf->ReadWord();
05094   if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
05095 
05096   for (uint i = 0; i < idcount; i++) {
05097     ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05098 
05099     if (spec == NULL) {
05100       grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05101       continue;
05102     }
05103 
05104     if (spec->grf_prop.grffile != NULL) {
05105       grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
05106       continue;
05107     }
05108 
05109     spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05110     spec->grf_prop.grffile        = _cur.grffile;
05111     spec->grf_prop.local_id       = objects[i];
05112   }
05113 }
05114 
05115 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
05116 {
05117   uint8 *railtypes = AllocaM(uint8, idcount);
05118   for (uint i = 0; i < idcount; i++) {
05119     railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
05120   }
05121 
05122   uint8 cidcount = buf->ReadByte();
05123   for (uint c = 0; c < cidcount; c++) {
05124     uint8 ctype = buf->ReadByte();
05125     uint16 groupid = buf->ReadWord();
05126     if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
05127 
05128     if (ctype >= RTSG_END) continue;
05129 
05130     extern RailtypeInfo _railtypes[RAILTYPE_END];
05131     for (uint i = 0; i < idcount; i++) {
05132       if (railtypes[i] != INVALID_RAILTYPE) {
05133         RailtypeInfo *rti = &_railtypes[railtypes[i]];
05134 
05135         rti->grffile[ctype] = _cur.grffile;
05136         rti->group[ctype] = _cur.spritegroups[groupid];
05137       }
05138     }
05139   }
05140 
05141   /* Railtypes do not use the default group. */
05142   buf->ReadWord();
05143 }
05144 
05145 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
05146 {
05147   uint8 *airports = AllocaM(uint8, idcount);
05148   for (uint i = 0; i < idcount; i++) {
05149     airports[i] = buf->ReadByte();
05150   }
05151 
05152   /* Skip the cargo type section, we only care about the default group */
05153   uint8 cidcount = buf->ReadByte();
05154   buf->Skip(cidcount * 3);
05155 
05156   uint16 groupid = buf->ReadWord();
05157   if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
05158 
05159   if (_cur.grffile->airportspec == NULL) {
05160     grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
05161     return;
05162   }
05163 
05164   for (uint i = 0; i < idcount; i++) {
05165     AirportSpec *as = _cur.grffile->airportspec[airports[i]];
05166 
05167     if (as == NULL) {
05168       grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
05169       continue;
05170     }
05171 
05172     as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05173   }
05174 }
05175 
05176 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
05177 {
05178   uint8 *airptiles = AllocaM(uint8, idcount);
05179   for (uint i = 0; i < idcount; i++) {
05180     airptiles[i] = buf->ReadByte();
05181   }
05182 
05183   /* Skip the cargo type section, we only care about the default group */
05184   uint8 cidcount = buf->ReadByte();
05185   buf->Skip(cidcount * 3);
05186 
05187   uint16 groupid = buf->ReadWord();
05188   if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
05189 
05190   if (_cur.grffile->airtspec == NULL) {
05191     grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
05192     return;
05193   }
05194 
05195   for (uint i = 0; i < idcount; i++) {
05196     AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
05197 
05198     if (airtsp == NULL) {
05199       grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
05200       continue;
05201     }
05202 
05203     airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05204   }
05205 }
05206 
05207 
05208 /* Action 0x03 */
05209 static void FeatureMapSpriteGroup(ByteReader *buf)
05210 {
05211   /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
05212    * id-list    := [<id>] [id-list]
05213    * cargo-list := <cargo-type> <cid> [cargo-list]
05214    *
05215    * B feature       see action 0
05216    * B n-id          bits 0-6: how many IDs this definition applies to
05217    *                 bit 7: if set, this is a wagon override definition (see below)
05218    * B ids           the IDs for which this definition applies
05219    * B num-cid       number of cargo IDs (sprite group IDs) in this definition
05220    *                 can be zero, in that case the def-cid is used always
05221    * B cargo-type    type of this cargo type (e.g. mail=2, wood=7, see below)
05222    * W cid           cargo ID (sprite group ID) for this type of cargo
05223    * W def-cid       default cargo ID (sprite group ID) */
05224 
05225   uint8 feature = buf->ReadByte();
05226   uint8 idcount = buf->ReadByte();
05227 
05228   /* If idcount is zero, this is a feature callback */
05229   if (idcount == 0) {
05230     /* Skip number of cargo ids? */
05231     buf->ReadByte();
05232     uint16 groupid = buf->ReadWord();
05233     if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
05234 
05235     grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
05236 
05237     AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
05238     return;
05239   }
05240 
05241   /* Mark the feature as used by the grf (generic callbacks do not count) */
05242   SetBit(_cur.grffile->grf_features, feature);
05243 
05244   grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
05245 
05246   switch (feature) {
05247     case GSF_TRAINS:
05248     case GSF_ROADVEHICLES:
05249     case GSF_SHIPS:
05250     case GSF_AIRCRAFT:
05251       VehicleMapSpriteGroup(buf, feature, idcount);
05252       return;
05253 
05254     case GSF_CANALS:
05255       CanalMapSpriteGroup(buf, idcount);
05256       return;
05257 
05258     case GSF_STATIONS:
05259       StationMapSpriteGroup(buf, idcount);
05260       return;
05261 
05262     case GSF_HOUSES:
05263       TownHouseMapSpriteGroup(buf, idcount);
05264       return;
05265 
05266     case GSF_INDUSTRIES:
05267       IndustryMapSpriteGroup(buf, idcount);
05268       return;
05269 
05270     case GSF_INDUSTRYTILES:
05271       IndustrytileMapSpriteGroup(buf, idcount);
05272       return;
05273 
05274     case GSF_CARGOES:
05275       CargoMapSpriteGroup(buf, idcount);
05276       return;
05277 
05278     case GSF_AIRPORTS:
05279       AirportMapSpriteGroup(buf, idcount);
05280       return;
05281 
05282     case GSF_OBJECTS:
05283       ObjectMapSpriteGroup(buf, idcount);
05284       break;
05285 
05286     case GSF_RAILTYPES:
05287       RailTypeMapSpriteGroup(buf, idcount);
05288       break;
05289 
05290     case GSF_AIRPORTTILES:
05291       AirportTileMapSpriteGroup(buf, idcount);
05292       return;
05293 
05294     default:
05295       grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
05296       return;
05297   }
05298 }
05299 
05300 /* Action 0x04 */
05301 static void FeatureNewName(ByteReader *buf)
05302 {
05303   /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
05304    *
05305    * B veh-type      see action 0 (as 00..07, + 0A
05306    *                 But IF veh-type = 48, then generic text
05307    * B language-id   If bit 6 is set, This is the extended language scheme,
05308    *                 with up to 64 language.
05309    *                 Otherwise, it is a mapping where set bits have meaning
05310    *                 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
05311    *                 Bit 7 set means this is a generic text, not a vehicle one (or else)
05312    * B num-veh       number of vehicles which are getting a new name
05313    * B/W offset      number of the first vehicle that gets a new name
05314    *                 Byte : ID of vehicle to change
05315    *                 Word : ID of string to change/add
05316    * S data          new texts, each of them zero-terminated, after
05317    *                 which the next name begins. */
05318 
05319   bool new_scheme = _cur.grffile->grf_version >= 7;
05320 
05321   uint8 feature  = buf->ReadByte();
05322   uint8 lang     = buf->ReadByte();
05323   uint8 num      = buf->ReadByte();
05324   bool generic   = HasBit(lang, 7);
05325   uint16 id;
05326   if (generic) {
05327     id = buf->ReadWord();
05328   } else if (feature <= GSF_AIRCRAFT) {
05329     id = buf->ReadExtendedByte();
05330   } else {
05331     id = buf->ReadByte();
05332   }
05333 
05334   ClrBit(lang, 7);
05335 
05336   uint16 endid = id + num;
05337 
05338   grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
05339                  id, endid, feature, lang);
05340 
05341   for (; id < endid && buf->HasData(); id++) {
05342     const char *name = buf->ReadString();
05343     grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
05344 
05345     switch (feature) {
05346       case GSF_TRAINS:
05347       case GSF_ROADVEHICLES:
05348       case GSF_SHIPS:
05349       case GSF_AIRCRAFT:
05350         if (!generic) {
05351           Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
05352           if (e == NULL) break;
05353           StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
05354           e->info.string_id = string;
05355         } else {
05356           AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05357         }
05358         break;
05359 
05360       case GSF_INDUSTRIES: {
05361         AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05362         break;
05363       }
05364 
05365       case GSF_HOUSES:
05366       default:
05367         switch (GB(id, 8, 8)) {
05368           case 0xC4: // Station class name
05369             if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05370               grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05371             } else {
05372               StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
05373               StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05374             }
05375             break;
05376 
05377           case 0xC5: // Station name
05378             if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05379               grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05380             } else {
05381               _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05382             }
05383             break;
05384 
05385           case 0xC7: // Airporttile name
05386             if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
05387               grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
05388             } else {
05389               _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05390             }
05391             break;
05392 
05393           case 0xC9: // House name
05394             if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
05395               grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
05396             } else {
05397               _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05398             }
05399             break;
05400 
05401           case 0xD0:
05402           case 0xD1:
05403           case 0xD2:
05404           case 0xD3:
05405           case 0xDC:
05406             AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05407             break;
05408 
05409           default:
05410             grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
05411             break;
05412         }
05413         break;
05414     }
05415   }
05416 }
05417 
05426 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
05427 {
05428 
05429   if (offset >= max_sprites) {
05430     grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
05431     uint orig_num = num;
05432     num = 0;
05433     return orig_num;
05434   }
05435 
05436   if (offset + num > max_sprites) {
05437     grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
05438     uint orig_num = num;
05439     num = max(max_sprites - offset, 0);
05440     return orig_num - num;
05441   }
05442 
05443   return 0;
05444 }
05445 
05446 
05448 enum Action5BlockType {
05449   A5BLOCK_FIXED,                
05450   A5BLOCK_ALLOW_OFFSET,         
05451   A5BLOCK_INVALID,              
05452 };
05454 struct Action5Type {
05455   Action5BlockType block_type;  
05456   SpriteID sprite_base;         
05457   uint16 min_sprites;           
05458   uint16 max_sprites;           
05459   const char *name;             
05460 };
05461 
05463 static const Action5Type _action5_types[] = {
05464   /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
05465   /* 0x00 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x00"                },
05466   /* 0x01 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x01"                },
05467   /* 0x02 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x02"                },
05468   /* 0x03 */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "Type 0x03"                },
05469   /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE,             1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,    "Signal graphics"          },
05470   /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE,              1, ELRAIL_SPRITE_COUNT,                         "Catenary graphics"        },
05471   /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE,              1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics"      },
05472   /* 0x07 */ { A5BLOCK_INVALID,      0,                           75, 0,                                           "TTDP GUI graphics"        }, // Not used by OTTD.
05473   /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE,              1, CANALS_SPRITE_COUNT,                         "Canal graphics"           },
05474   /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE,              1, ONEWAY_SPRITE_COUNT,                         "One way road graphics"    },
05475   /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE,              1, TWOCCMAP_SPRITE_COUNT,                       "2CC colour maps"          },
05476   /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE,             1, TRAMWAY_SPRITE_COUNT,                        "Tramway graphics"         },
05477   /* 0x0C */ { A5BLOCK_INVALID,      0,                          133, 0,                                           "Snowy temperate tree"     }, // Not yet used by OTTD.
05478   /* 0x0D */ { A5BLOCK_FIXED,        SPR_SHORE_BASE,              16, SPR_SHORE_SPRITE_COUNT,                      "Shore graphics"           },
05479   /* 0x0E */ { A5BLOCK_INVALID,      0,                            0, 0,                                           "New Signals graphics"     }, // Not yet used by OTTD.
05480   /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE,   1, TRACKS_FOR_SLOPES_SPRITE_COUNT,              "Sloped rail track"        },
05481   /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE,            1, AIRPORTX_SPRITE_COUNT,                       "Airport graphics"         },
05482   /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE,            1, ROADSTOP_SPRITE_COUNT,                       "Road stop graphics"       },
05483   /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE,            1, AQUEDUCT_SPRITE_COUNT,                       "Aqueduct graphics"        },
05484   /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE,            1, AUTORAIL_SPRITE_COUNT,                       "Autorail graphics"        },
05485   /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE,               1, FLAGS_SPRITE_COUNT,                          "Flag graphics"            },
05486   /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE,             1, OPENTTD_SPRITE_COUNT,                        "OpenTTD GUI graphics"     },
05487   /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE,     1, SPR_AIRPORT_PREVIEW_COUNT,                   "Airport preview graphics" },
05488   /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE,     1, RAILTYPE_TUNNEL_BASE_COUNT,                  "Railtype tunnel base"     },
05489 };
05490 
05491 /* Action 0x05 */
05492 static void GraphicsNew(ByteReader *buf)
05493 {
05494   /* <05> <graphics-type> <num-sprites> <other data...>
05495    *
05496    * B graphics-type What set of graphics the sprites define.
05497    * E num-sprites   How many sprites are in this set?
05498    * V other data    Graphics type specific data.  Currently unused. */
05499   /* TODO */
05500 
05501   uint8 type = buf->ReadByte();
05502   uint16 num = buf->ReadExtendedByte();
05503   uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
05504   ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
05505 
05506   if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
05507     /* Special not-TTDP-compatible case used in openttd.grf
05508      * Missing shore sprites and initialisation of SPR_SHORE_BASE */
05509     grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
05510     LoadNextSprite(SPR_SHORE_BASE +  0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
05511     LoadNextSprite(SPR_SHORE_BASE +  5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
05512     LoadNextSprite(SPR_SHORE_BASE +  7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
05513     LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
05514     LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
05515     LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
05516     LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
05517     LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
05518     LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
05519     LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
05520     if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
05521     return;
05522   }
05523 
05524   /* Supported type? */
05525   if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
05526     grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
05527     _cur.skip_sprites = num;
05528     return;
05529   }
05530 
05531   const Action5Type *action5_type = &_action5_types[type];
05532 
05533   /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
05534    * except for the long version of the shore type:
05535    * Ignore offset if not allowed */
05536   if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
05537     grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
05538     offset = 0;
05539   }
05540 
05541   /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
05542    * This does not make sense, if <offset> is allowed */
05543   if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
05544     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);
05545     _cur.skip_sprites = num;
05546     return;
05547   }
05548 
05549   /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
05550   uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
05551   SpriteID replace = action5_type->sprite_base + offset;
05552 
05553   /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
05554   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);
05555 
05556   for (; num > 0; num--) {
05557     _cur.nfo_line++;
05558     LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
05559   }
05560 
05561   if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
05562 
05563   _cur.skip_sprites = skip_num;
05564 }
05565 
05566 /* Action 0x05 (SKIP) */
05567 static void SkipAct5(ByteReader *buf)
05568 {
05569   /* Ignore type byte */
05570   buf->ReadByte();
05571 
05572   /* Skip the sprites of this action */
05573   _cur.skip_sprites = buf->ReadExtendedByte();
05574 
05575   grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
05576 }
05577 
05583 void CheckForMissingSprites()
05584 {
05585   /* Don't break out quickly, but allow to check the other
05586    * sprites as well, so we can give the best information. */
05587   bool missing = false;
05588   for (uint8 i = 0; i < lengthof(_action5_types); i++) {
05589     const Action5Type *type = &_action5_types[i];
05590     if (type->block_type == A5BLOCK_INVALID) continue;
05591 
05592     for (uint j = 0; j < type->max_sprites; j++) {
05593       if (!SpriteExists(type->sprite_base + j)) {
05594         DEBUG(grf, 0, "%s sprites are missing", type->name);
05595         missing = true;
05596         /* No need to log more of the same. */
05597         break;
05598       }
05599     }
05600   }
05601 
05602   if (missing) {
05603     ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
05604   }
05605 }
05606 
05618 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
05619 {
05620   switch (param) {
05621     case 0x00: // current date
05622       *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
05623       return true;
05624 
05625     case 0x01: // current year
05626       *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
05627       return true;
05628 
05629     case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
05630       YearMonthDay ymd;
05631       ConvertDateToYMD(_date, &ymd);
05632       Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
05633       *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
05634       return true;
05635     }
05636 
05637     case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
05638       *value = _settings_game.game_creation.landscape;
05639       return true;
05640 
05641     case 0x06: // road traffic side, bit 4 clear=left, set=right
05642       *value = _settings_game.vehicle.road_side << 4;
05643       return true;
05644 
05645     case 0x09: // date fraction
05646       *value = _date_fract * 885;
05647       return true;
05648 
05649     case 0x0A: // animation counter
05650       *value = _tick_counter;
05651       return true;
05652 
05653     case 0x0B: { // TTDPatch version
05654       uint major    = 2;
05655       uint minor    = 6;
05656       uint revision = 1; // special case: 2.0.1 is 2.0.10
05657       uint build    = 1382;
05658       *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05659       return true;
05660     }
05661 
05662     case 0x0D: // TTD Version, 00=DOS, 01=Windows
05663       *value = _cur.grfconfig->palette & GRFP_USE_MASK;
05664       return true;
05665 
05666     case 0x0E: // Y-offset for train sprites
05667       *value = _cur.grffile->traininfo_vehicle_pitch;
05668       return true;
05669 
05670     case 0x0F: // Rail track type cost factors
05671       *value = 0;
05672       SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
05673       if (_settings_game.vehicle.disable_elrails) {
05674         /* skip elrail multiplier - disabled */
05675         SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
05676       } else {
05677         SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
05678         /* Skip monorail multiplier - no space in result */
05679       }
05680       SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
05681       return true;
05682 
05683     case 0x11: // current rail tool type
05684       *value = 0; // constant fake value to avoid desync
05685       return true;
05686 
05687     case 0x12: // Game mode
05688       *value = _game_mode;
05689       return true;
05690 
05691     /* case 0x13: // Tile refresh offset to left    not implemented */
05692     /* case 0x14: // Tile refresh offset to right   not implemented */
05693     /* case 0x15: // Tile refresh offset upwards    not implemented */
05694     /* case 0x16: // Tile refresh offset downwards  not implemented */
05695     /* case 0x17: // temperate snow line            not implemented */
05696 
05697     case 0x1A: // Always -1
05698       *value = UINT_MAX;
05699       return true;
05700 
05701     case 0x1B: // Display options
05702       *value = 0x3F; // constant fake value to avoid desync
05703       return true;
05704 
05705     case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
05706       *value = 1;
05707       return true;
05708 
05709     case 0x1E: // Miscellaneous GRF features
05710       *value = _misc_grf_features;
05711 
05712       /* Add the local flags */
05713       assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05714       if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05715       return true;
05716 
05717     /* case 0x1F: // locale dependent settings not implemented to avoid desync */
05718 
05719     case 0x20: { // snow line height
05720       byte snowline = GetSnowLine();
05721       if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
05722         *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
05723       } else {
05724         /* No snow */
05725         *value = 0xFF;
05726       }
05727       return true;
05728     }
05729 
05730     case 0x21: // OpenTTD version
05731       *value = _openttd_newgrf_version;
05732       return true;
05733 
05734     case 0x22: // difficulty level
05735       *value = SP_CUSTOM;
05736       return true;
05737 
05738     case 0x23: // long format date
05739       *value = _date;
05740       return true;
05741 
05742     case 0x24: // long format year
05743       *value = _cur_year;
05744       return true;
05745 
05746     default: return false;
05747   }
05748 }
05749 
05750 static uint32 GetParamVal(byte param, uint32 *cond_val)
05751 {
05752   /* First handle variable common with VarAction2 */
05753   uint32 value;
05754   if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
05755 
05756   /* Non-common variable */
05757   switch (param) {
05758     case 0x84: { // GRF loading stage
05759       uint32 res = 0;
05760 
05761       if (_cur.stage > GLS_INIT) SetBit(res, 0);
05762       if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
05763       if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
05764       return res;
05765     }
05766 
05767     case 0x85: // TTDPatch flags, only for bit tests
05768       if (cond_val == NULL) {
05769         /* Supported in Action 0x07 and 0x09, not 0x0D */
05770         return 0;
05771       } else {
05772         uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05773         *cond_val %= 0x20;
05774         return param_val;
05775       }
05776 
05777     case 0x88: // GRF ID check
05778       return 0;
05779 
05780     /* case 0x99: Global ID offest not implemented */
05781 
05782     default:
05783       /* GRF Parameter */
05784       if (param < 0x80) return _cur.grffile->GetParam(param);
05785 
05786       /* In-game variable. */
05787       grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05788       return UINT_MAX;
05789   }
05790 }
05791 
05792 /* Action 0x06 */
05793 static void CfgApply(ByteReader *buf)
05794 {
05795   /* <06> <param-num> <param-size> <offset> ... <FF>
05796    *
05797    * B param-num     Number of parameter to substitute (First = "zero")
05798    *                 Ignored if that parameter was not specified in newgrf.cfg
05799    * B param-size    How many bytes to replace.  If larger than 4, the
05800    *                 bytes of the following parameter are used.  In that
05801    *                 case, nothing is applied unless *all* parameters
05802    *                 were specified.
05803    * B offset        Offset into data from beginning of next sprite
05804    *                 to place where parameter is to be stored. */
05805 
05806   /* Preload the next sprite */
05807   size_t pos = FioGetPos();
05808   uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
05809   uint8 type = FioReadByte();
05810   byte *preload_sprite = NULL;
05811 
05812   /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
05813   if (type == 0xFF) {
05814     preload_sprite = MallocT<byte>(num);
05815     FioReadBlock(preload_sprite, num);
05816   }
05817 
05818   /* Reset the file position to the start of the next sprite */
05819   FioSeekTo(pos, SEEK_SET);
05820 
05821   if (type != 0xFF) {
05822     grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05823     free(preload_sprite);
05824     return;
05825   }
05826 
05827   GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
05828   GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05829   if (it != _grf_line_to_action6_sprite_override.end()) {
05830     free(preload_sprite);
05831     preload_sprite = _grf_line_to_action6_sprite_override[location];
05832   } else {
05833     _grf_line_to_action6_sprite_override[location] = preload_sprite;
05834   }
05835 
05836   /* Now perform the Action 0x06 on our data. */
05837 
05838   for (;;) {
05839     uint i;
05840     uint param_num;
05841     uint param_size;
05842     uint offset;
05843     bool add_value;
05844 
05845     /* Read the parameter to apply. 0xFF indicates no more data to change. */
05846     param_num = buf->ReadByte();
05847     if (param_num == 0xFF) break;
05848 
05849     /* Get the size of the parameter to use. If the size covers multiple
05850      * double words, sequential parameter values are used. */
05851     param_size = buf->ReadByte();
05852 
05853     /* Bit 7 of param_size indicates we should add to the original value
05854      * instead of replacing it. */
05855     add_value  = HasBit(param_size, 7);
05856     param_size = GB(param_size, 0, 7);
05857 
05858     /* Where to apply the data to within the pseudo sprite data. */
05859     offset     = buf->ReadExtendedByte();
05860 
05861     /* If the parameter is a GRF parameter (not an internal variable) check
05862      * if it (and all further sequential parameters) has been defined. */
05863     if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
05864       grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05865       break;
05866     }
05867 
05868     grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05869 
05870     bool carry = false;
05871     for (i = 0; i < param_size && offset + i < num; i++) {
05872       uint32 value = GetParamVal(param_num + i / 4, NULL);
05873       /* Reset carry flag for each iteration of the variable (only really
05874        * matters if param_size is greater than 4) */
05875       if (i % 4 == 0) carry = false;
05876 
05877       if (add_value) {
05878         uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05879         preload_sprite[offset + i] = GB(new_value, 0, 8);
05880         /* Check if the addition overflowed */
05881         carry = new_value >= 256;
05882       } else {
05883         preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05884       }
05885     }
05886   }
05887 }
05888 
05898 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05899 {
05900   GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05901   error->data = strdup(_cur.grfconfig->GetName());
05902 }
05903 
05904 /* Action 0x07
05905  * Action 0x09 */
05906 static void SkipIf(ByteReader *buf)
05907 {
05908   /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
05909    *
05910    * B param-num
05911    * B param-size
05912    * B condition-type
05913    * V value
05914    * B num-sprites */
05915   /* TODO: More params. More condition types. */
05916   uint32 cond_val = 0;
05917   uint32 mask = 0;
05918   bool result;
05919 
05920   uint8 param     = buf->ReadByte();
05921   uint8 paramsize = buf->ReadByte();
05922   uint8 condtype  = buf->ReadByte();
05923 
05924   if (condtype < 2) {
05925     /* Always 1 for bit tests, the given value should be ignored. */
05926     paramsize = 1;
05927   }
05928 
05929   switch (paramsize) {
05930     case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05931     case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05932     case 2: cond_val = buf->ReadWord();  mask = 0x0000FFFF; break;
05933     case 1: cond_val = buf->ReadByte();  mask = 0x000000FF; break;
05934     default: break;
05935   }
05936 
05937   if (param < 0x80 && _cur.grffile->param_end <= param) {
05938     grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05939     return;
05940   }
05941 
05942   uint32 param_val = GetParamVal(param, &cond_val);
05943 
05944   grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05945 
05946   /*
05947    * Parameter (variable in specs) 0x88 can only have GRF ID checking
05948    * conditions, except conditions 0x0B, 0x0C (cargo availability) and
05949    * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
05950    * So, when the condition type is one of those, the specific variable
05951    * 0x88 code is skipped, so the "general" code for the cargo
05952    * availability conditions kicks in.
05953    */
05954   if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05955     /* GRF ID checks */
05956 
05957     GRFConfig *c = GetGRFConfig(cond_val, mask);
05958 
05959     if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
05960       DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05961       c = NULL;
05962     }
05963 
05964     if (condtype != 10 && c == NULL) {
05965       grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05966       return;
05967     }
05968 
05969     switch (condtype) {
05970       /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
05971       case 0x06: // Is GRFID active?
05972         result = c->status == GCS_ACTIVATED;
05973         break;
05974 
05975       case 0x07: // Is GRFID non-active?
05976         result = c->status != GCS_ACTIVATED;
05977         break;
05978 
05979       case 0x08: // GRFID is not but will be active?
05980         result = c->status == GCS_INITIALISED;
05981         break;
05982 
05983       case 0x09: // GRFID is or will be active?
05984         result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05985         break;
05986 
05987       case 0x0A: // GRFID is not nor will be active
05988         /* This is the only condtype that doesn't get ignored if the GRFID is not found */
05989         result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05990         break;
05991 
05992       default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05993     }
05994   } else {
05995     /* Parameter or variable tests */
05996     switch (condtype) {
05997       case 0x00: result = !!(param_val & (1 << cond_val));
05998         break;
05999       case 0x01: result = !(param_val & (1 << cond_val));
06000         break;
06001       case 0x02: result = (param_val & mask) == cond_val;
06002         break;
06003       case 0x03: result = (param_val & mask) != cond_val;
06004         break;
06005       case 0x04: result = (param_val & mask) < cond_val;
06006         break;
06007       case 0x05: result = (param_val & mask) > cond_val;
06008         break;
06009       case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
06010         break;
06011       case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
06012         break;
06013       case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
06014         break;
06015       case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
06016         break;
06017 
06018       default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
06019     }
06020   }
06021 
06022   if (!result) {
06023     grfmsg(2, "SkipIf: Not skipping sprites, test was false");
06024     return;
06025   }
06026 
06027   uint8 numsprites = buf->ReadByte();
06028 
06029   /* numsprites can be a GOTO label if it has been defined in the GRF
06030    * file. The jump will always be the first matching label that follows
06031    * the current nfo_line. If no matching label is found, the first matching
06032    * label in the file is used. */
06033   GRFLabel *choice = NULL;
06034   for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
06035     if (label->label != numsprites) continue;
06036 
06037     /* Remember a goto before the current line */
06038     if (choice == NULL) choice = label;
06039     /* If we find a label here, this is definitely good */
06040     if (label->nfo_line > _cur.nfo_line) {
06041       choice = label;
06042       break;
06043     }
06044   }
06045 
06046   if (choice != NULL) {
06047     grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
06048     FioSeekTo(choice->pos, SEEK_SET);
06049     _cur.nfo_line = choice->nfo_line;
06050     return;
06051   }
06052 
06053   grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
06054   _cur.skip_sprites = numsprites;
06055   if (_cur.skip_sprites == 0) {
06056     /* Zero means there are no sprites to skip, so
06057      * we use -1 to indicate that all further
06058      * sprites should be skipped. */
06059     _cur.skip_sprites = -1;
06060 
06061     /* If an action 8 hasn't been encountered yet, disable the grf. */
06062     if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
06063       DisableGrf();
06064     }
06065   }
06066 }
06067 
06068 
06069 /* Action 0x08 (GLS_FILESCAN) */
06070 static void ScanInfo(ByteReader *buf)
06071 {
06072   uint8 grf_version = buf->ReadByte();
06073   uint32 grfid      = buf->ReadDWord();
06074   const char *name  = buf->ReadString();
06075 
06076   _cur.grfconfig->ident.grfid = grfid;
06077 
06078   if (grf_version < 2 || grf_version > 8) {
06079     SetBit(_cur.grfconfig->flags, GCF_INVALID);
06080     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);
06081   }
06082 
06083   /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
06084   if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
06085 
06086   AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
06087 
06088   if (buf->HasData()) {
06089     const char *info = buf->ReadString();
06090     AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
06091   }
06092 
06093   /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
06094   _cur.skip_sprites = -1;
06095 }
06096 
06097 /* Action 0x08 */
06098 static void GRFInfo(ByteReader *buf)
06099 {
06100   /* <08> <version> <grf-id> <name> <info>
06101    *
06102    * B version       newgrf version, currently 06
06103    * 4*B grf-id      globally unique ID of this .grf file
06104    * S name          name of this .grf set
06105    * S info          string describing the set, and e.g. author and copyright */
06106 
06107   uint8 version    = buf->ReadByte();
06108   uint32 grfid     = buf->ReadDWord();
06109   const char *name = buf->ReadString();
06110 
06111   if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
06112     DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
06113     return;
06114   }
06115 
06116   if (_cur.grffile->grfid != grfid) {
06117     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));
06118     _cur.grffile->grfid = grfid;
06119   }
06120 
06121   _cur.grffile->grf_version = version;
06122   _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
06123 
06124   /* Do swap the GRFID for displaying purposes since people expect that */
06125   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);
06126 }
06127 
06128 /* Action 0x0A */
06129 static void SpriteReplace(ByteReader *buf)
06130 {
06131   /* <0A> <num-sets> <set1> [<set2> ...]
06132    * <set>: <num-sprites> <first-sprite>
06133    *
06134    * B num-sets      How many sets of sprites to replace.
06135    * Each set:
06136    * B num-sprites   How many sprites are in this set
06137    * W first-sprite  First sprite number to replace */
06138 
06139   uint8 num_sets = buf->ReadByte();
06140 
06141   for (uint i = 0; i < num_sets; i++) {
06142     uint8 num_sprites = buf->ReadByte();
06143     uint16 first_sprite = buf->ReadWord();
06144 
06145     grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
06146       i, num_sprites, first_sprite
06147     );
06148 
06149     for (uint j = 0; j < num_sprites; j++) {
06150       int load_index = first_sprite + j;
06151       _cur.nfo_line++;
06152       LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
06153 
06154       /* Shore sprites now located at different addresses.
06155        * So detect when the old ones get replaced. */
06156       if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
06157         if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06158       }
06159     }
06160   }
06161 }
06162 
06163 /* Action 0x0A (SKIP) */
06164 static void SkipActA(ByteReader *buf)
06165 {
06166   uint8 num_sets = buf->ReadByte();
06167 
06168   for (uint i = 0; i < num_sets; i++) {
06169     /* Skip the sprites this replaces */
06170     _cur.skip_sprites += buf->ReadByte();
06171     /* But ignore where they go */
06172     buf->ReadWord();
06173   }
06174 
06175   grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
06176 }
06177 
06178 /* Action 0x0B */
06179 static void GRFLoadError(ByteReader *buf)
06180 {
06181   /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
06182    *
06183    * B severity      00: notice, contine loading grf file
06184    *                 01: warning, continue loading grf file
06185    *                 02: error, but continue loading grf file, and attempt
06186    *                     loading grf again when loading or starting next game
06187    *                 03: error, abort loading and prevent loading again in
06188    *                     the future (only when restarting the patch)
06189    * B language-id   see action 4, use 1F for built-in error messages
06190    * B message-id    message to show, see below
06191    * S message       for custom messages (message-id FF), text of the message
06192    *                 not present for built-in messages.
06193    * V data          additional data for built-in (or custom) messages
06194    * B parnum        parameter numbers to be shown in the message (maximum of 2) */
06195 
06196   static const StringID msgstr[] = {
06197     STR_NEWGRF_ERROR_VERSION_NUMBER,
06198     STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
06199     STR_NEWGRF_ERROR_UNSET_SWITCH,
06200     STR_NEWGRF_ERROR_INVALID_PARAMETER,
06201     STR_NEWGRF_ERROR_LOAD_BEFORE,
06202     STR_NEWGRF_ERROR_LOAD_AFTER,
06203     STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
06204   };
06205 
06206   static const StringID sevstr[] = {
06207     STR_NEWGRF_ERROR_MSG_INFO,
06208     STR_NEWGRF_ERROR_MSG_WARNING,
06209     STR_NEWGRF_ERROR_MSG_ERROR,
06210     STR_NEWGRF_ERROR_MSG_FATAL
06211   };
06212 
06213   byte severity   = buf->ReadByte();
06214   byte lang       = buf->ReadByte();
06215   byte message_id = buf->ReadByte();
06216 
06217   /* Skip the error if it isn't valid for the current language. */
06218   if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
06219 
06220   /* Skip the error until the activation stage unless bit 7 of the severity
06221    * is set. */
06222   if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
06223     grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
06224     return;
06225   }
06226   ClrBit(severity, 7);
06227 
06228   if (severity >= lengthof(sevstr)) {
06229     grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
06230     severity = 2;
06231   } else if (severity == 3) {
06232     /* This is a fatal error, so make sure the GRF is deactivated and no
06233      * more of it gets loaded. */
06234     DisableGrf();
06235 
06236     /* Make sure we show fatal errors, instead of silly infos from before */
06237     delete _cur.grfconfig->error;
06238     _cur.grfconfig->error = NULL;
06239   }
06240 
06241   if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
06242     grfmsg(7, "GRFLoadError: Invalid message id.");
06243     return;
06244   }
06245 
06246   if (buf->Remaining() <= 1) {
06247     grfmsg(7, "GRFLoadError: No message data supplied.");
06248     return;
06249   }
06250 
06251   /* For now we can only show one message per newgrf file. */
06252   if (_cur.grfconfig->error != NULL) return;
06253 
06254   GRFError *error = new GRFError(sevstr[severity]);
06255 
06256   if (message_id == 0xFF) {
06257     /* This is a custom error message. */
06258     if (buf->HasData()) {
06259       const char *message = buf->ReadString();
06260 
06261       error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
06262     } else {
06263       grfmsg(7, "GRFLoadError: No custom message supplied.");
06264       error->custom_message = strdup("");
06265     }
06266   } else {
06267     error->message = msgstr[message_id];
06268   }
06269 
06270   if (buf->HasData()) {
06271     const char *data = buf->ReadString();
06272 
06273     error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
06274   } else {
06275     grfmsg(7, "GRFLoadError: No message data supplied.");
06276     error->data = strdup("");
06277   }
06278 
06279   /* Only two parameter numbers can be used in the string. */
06280   for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
06281     uint param_number = buf->ReadByte();
06282     error->param_value[i] = _cur.grffile->GetParam(param_number);
06283   }
06284 
06285   _cur.grfconfig->error = error;
06286 }
06287 
06288 /* Action 0x0C */
06289 static void GRFComment(ByteReader *buf)
06290 {
06291   /* <0C> [<ignored...>]
06292    *
06293    * V ignored       Anything following the 0C is ignored */
06294 
06295   if (!buf->HasData()) return;
06296 
06297   const char *text = buf->ReadString();
06298   grfmsg(2, "GRFComment: %s", text);
06299 }
06300 
06301 /* Action 0x0D (GLS_SAFETYSCAN) */
06302 static void SafeParamSet(ByteReader *buf)
06303 {
06304   uint8 target = buf->ReadByte();
06305 
06306   /* Only writing GRF parameters is considered safe */
06307   if (target < 0x80) return;
06308 
06309   /* GRM could be unsafe, but as here it can only happen after other GRFs
06310    * are loaded, it should be okay. If the GRF tried to use the slots it
06311    * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
06312    * sprites  is considered safe. */
06313 
06314   SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06315 
06316   /* Skip remainder of GRF */
06317   _cur.skip_sprites = -1;
06318 }
06319 
06320 
06321 static uint32 GetPatchVariable(uint8 param)
06322 {
06323   switch (param) {
06324     /* start year - 1920 */
06325     case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
06326 
06327     /* freight trains weight factor */
06328     case 0x0E: return _settings_game.vehicle.freight_trains;
06329 
06330     /* empty wagon speed increase */
06331     case 0x0F: return 0;
06332 
06333     /* plane speed factor; our patch option is reversed from TTDPatch's,
06334      * the following is good for 1x, 2x and 4x (most common?) and...
06335      * well not really for 3x. */
06336     case 0x10:
06337       switch (_settings_game.vehicle.plane_speed) {
06338         default:
06339         case 4: return 1;
06340         case 3: return 2;
06341         case 2: return 2;
06342         case 1: return 4;
06343       }
06344 
06345 
06346     /* 2CC colourmap base sprite */
06347     case 0x11: return SPR_2CCMAP_BASE;
06348 
06349     /* map size: format = -MABXYSS
06350      * M  : the type of map
06351      *       bit 0 : set   : squared map. Bit 1 is now not relevant
06352      *               clear : rectangle map. Bit 1 will indicate the bigger edge of the map
06353      *       bit 1 : set   : Y is the bigger edge. Bit 0 is clear
06354      *               clear : X is the bigger edge.
06355      * A  : minimum edge(log2) of the map
06356      * B  : maximum edge(log2) of the map
06357      * XY : edges(log2) of each side of the map.
06358      * SS : combination of both X and Y, thus giving the size(log2) of the map
06359      */
06360     case 0x13: {
06361       byte map_bits = 0;
06362       byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
06363       byte log_Y = MapLogY() - 6;
06364       byte max_edge = max(log_X, log_Y);
06365 
06366       if (log_X == log_Y) { // we have a squared map, since both edges are identical
06367         SetBit(map_bits, 0);
06368       } else {
06369         if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
06370       }
06371 
06372       return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
06373         (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
06374     }
06375 
06376     /* The maximum height of the map. */
06377     case 0x14:
06378       return MAX_TILE_HEIGHT;
06379 
06380     default:
06381       grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
06382       return 0;
06383   }
06384 }
06385 
06386 
06387 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
06388 {
06389   uint start = 0;
06390   uint size  = 0;
06391 
06392   if (op == 6) {
06393     /* Return GRFID of set that reserved ID */
06394     return grm[_cur.grffile->GetParam(target)];
06395   }
06396 
06397   /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
06398   if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
06399 
06400   for (uint i = start; i < num_ids; i++) {
06401     if (grm[i] == 0) {
06402       size++;
06403     } else {
06404       if (op == 2 || op == 3) break;
06405       start = i + 1;
06406       size = 0;
06407     }
06408 
06409     if (size == count) break;
06410   }
06411 
06412   if (size == count) {
06413     /* Got the slot... */
06414     if (op == 0 || op == 3) {
06415       grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
06416       for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
06417     }
06418     return start;
06419   }
06420 
06421   /* Unable to allocate */
06422   if (op != 4 && op != 5) {
06423     /* Deactivate GRF */
06424     grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
06425     DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06426     return UINT_MAX;
06427   }
06428 
06429   grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
06430   return UINT_MAX;
06431 }
06432 
06433 
06435 static void ParamSet(ByteReader *buf)
06436 {
06437   /* <0D> <target> <operation> <source1> <source2> [<data>]
06438    *
06439    * B target        parameter number where result is stored
06440    * B operation     operation to perform, see below
06441    * B source1       first source operand
06442    * B source2       second source operand
06443    * D data          data to use in the calculation, not necessary
06444    *                 if both source1 and source2 refer to actual parameters
06445    *
06446    * Operations
06447    * 00      Set parameter equal to source1
06448    * 01      Addition, source1 + source2
06449    * 02      Subtraction, source1 - source2
06450    * 03      Unsigned multiplication, source1 * source2 (both unsigned)
06451    * 04      Signed multiplication, source1 * source2 (both signed)
06452    * 05      Unsigned bit shift, source1 by source2 (source2 taken to be a
06453    *         signed quantity; left shift if positive and right shift if
06454    *         negative, source1 is unsigned)
06455    * 06      Signed bit shift, source1 by source2
06456    *         (source2 like in 05, and source1 as well)
06457    */
06458 
06459   uint8 target = buf->ReadByte();
06460   uint8 oper   = buf->ReadByte();
06461   uint32 src1  = buf->ReadByte();
06462   uint32 src2  = buf->ReadByte();
06463 
06464   uint32 data = 0;
06465   if (buf->Remaining() >= 4) data = buf->ReadDWord();
06466 
06467   /* You can add 80 to the operation to make it apply only if the target
06468    * is not defined yet.  In this respect, a parameter is taken to be
06469    * defined if any of the following applies:
06470    * - it has been set to any value in the newgrf(w).cfg parameter list
06471    * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
06472    *   an earlier action D */
06473   if (HasBit(oper, 7)) {
06474     if (target < 0x80 && target < _cur.grffile->param_end) {
06475       grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
06476       return;
06477     }
06478 
06479     oper = GB(oper, 0, 7);
06480   }
06481 
06482   if (src2 == 0xFE) {
06483     if (GB(data, 0, 8) == 0xFF) {
06484       if (data == 0x0000FFFF) {
06485         /* Patch variables */
06486         src1 = GetPatchVariable(src1);
06487       } else {
06488         /* GRF Resource Management */
06489         uint8  op      = src1;
06490         uint8  feature = GB(data, 8, 8);
06491         uint16 count   = GB(data, 16, 16);
06492 
06493         if (_cur.stage == GLS_RESERVE) {
06494           if (feature == 0x08) {
06495             /* General sprites */
06496             if (op == 0) {
06497               /* Check if the allocated sprites will fit below the original sprite limit */
06498               if (_cur.spriteid + count >= 16384) {
06499                 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
06500                 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06501                 return;
06502               }
06503 
06504               /* Reserve space at the current sprite ID */
06505               grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
06506               _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
06507               _cur.spriteid += count;
06508             }
06509           }
06510           /* Ignore GRM result during reservation */
06511           src1 = 0;
06512         } else if (_cur.stage == GLS_ACTIVATION) {
06513           switch (feature) {
06514             case 0x00: // Trains
06515             case 0x01: // Road Vehicles
06516             case 0x02: // Ships
06517             case 0x03: // Aircraft
06518               if (!_settings_game.vehicle.dynamic_engines) {
06519                 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
06520                 if (_cur.skip_sprites == -1) return;
06521               } else {
06522                 /* GRM does not apply for dynamic engine allocation. */
06523                 switch (op) {
06524                   case 2:
06525                   case 3:
06526                     src1 = _cur.grffile->GetParam(target);
06527                     break;
06528 
06529                   default:
06530                     src1 = 0;
06531                     break;
06532                 }
06533               }
06534               break;
06535 
06536             case 0x08: // General sprites
06537               switch (op) {
06538                 case 0:
06539                   /* Return space reserved during reservation stage */
06540                   src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
06541                   grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
06542                   break;
06543 
06544                 case 1:
06545                   src1 = _cur.spriteid;
06546                   break;
06547 
06548                 default:
06549                   grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
06550                   return;
06551               }
06552               break;
06553 
06554             case 0x0B: // Cargo
06555               /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
06556               src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
06557               if (_cur.skip_sprites == -1) return;
06558               break;
06559 
06560             default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
06561           }
06562         } else {
06563           /* Ignore GRM during initialization */
06564           src1 = 0;
06565         }
06566       }
06567     } else {
06568       /* Read another GRF File's parameter */
06569       const GRFFile *file = GetFileByGRFID(data);
06570       GRFConfig *c = GetGRFConfig(data);
06571       if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
06572         /* Disable the read GRF if it is a static NewGRF. */
06573         DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
06574         src1 = 0;
06575       } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
06576         src1 = 0;
06577       } else if (src1 == 0xFE) {
06578         src1 = c->version;
06579       } else {
06580         src1 = file->GetParam(src1);
06581       }
06582     }
06583   } else {
06584     /* The source1 and source2 operands refer to the grf parameter number
06585      * like in action 6 and 7.  In addition, they can refer to the special
06586      * variables available in action 7, or they can be FF to use the value
06587      * of <data>.  If referring to parameters that are undefined, a value
06588      * of 0 is used instead.  */
06589     src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
06590     src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
06591   }
06592 
06593   /* TODO: You can access the parameters of another GRF file by using
06594    * source2=FE, source1=the other GRF's parameter number and data=GRF
06595    * ID.  This is only valid with operation 00 (set).  If the GRF ID
06596    * cannot be found, a value of 0 is used for the parameter value
06597    * instead. */
06598 
06599   uint32 res;
06600   switch (oper) {
06601     case 0x00:
06602       res = src1;
06603       break;
06604 
06605     case 0x01:
06606       res = src1 + src2;
06607       break;
06608 
06609     case 0x02:
06610       res = src1 - src2;
06611       break;
06612 
06613     case 0x03:
06614       res = src1 * src2;
06615       break;
06616 
06617     case 0x04:
06618       res = (int32)src1 * (int32)src2;
06619       break;
06620 
06621     case 0x05:
06622       if ((int32)src2 < 0) {
06623         res = src1 >> -(int32)src2;
06624       } else {
06625         res = src1 << src2;
06626       }
06627       break;
06628 
06629     case 0x06:
06630       if ((int32)src2 < 0) {
06631         res = (int32)src1 >> -(int32)src2;
06632       } else {
06633         res = (int32)src1 << src2;
06634       }
06635       break;
06636 
06637     case 0x07: // Bitwise AND
06638       res = src1 & src2;
06639       break;
06640 
06641     case 0x08: // Bitwise OR
06642       res = src1 | src2;
06643       break;
06644 
06645     case 0x09: // Unsigned division
06646       if (src2 == 0) {
06647         res = src1;
06648       } else {
06649         res = src1 / src2;
06650       }
06651       break;
06652 
06653     case 0x0A: // Signed divison
06654       if (src2 == 0) {
06655         res = src1;
06656       } else {
06657         res = (int32)src1 / (int32)src2;
06658       }
06659       break;
06660 
06661     case 0x0B: // Unsigned modulo
06662       if (src2 == 0) {
06663         res = src1;
06664       } else {
06665         res = src1 % src2;
06666       }
06667       break;
06668 
06669     case 0x0C: // Signed modulo
06670       if (src2 == 0) {
06671         res = src1;
06672       } else {
06673         res = (int32)src1 % (int32)src2;
06674       }
06675       break;
06676 
06677     default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06678   }
06679 
06680   switch (target) {
06681     case 0x8E: // Y-Offset for train sprites
06682       _cur.grffile->traininfo_vehicle_pitch = res;
06683       break;
06684 
06685     case 0x8F: { // Rail track type cost factors
06686       extern RailtypeInfo _railtypes[RAILTYPE_END];
06687       _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06688       if (_settings_game.vehicle.disable_elrails) {
06689         _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06690         _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06691       } else {
06692         _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06693         _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06694       }
06695       _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06696       break;
06697     }
06698 
06699     /* @todo implement */
06700     case 0x93: // Tile refresh offset to left
06701     case 0x94: // Tile refresh offset to right
06702     case 0x95: // Tile refresh offset upwards
06703     case 0x96: // Tile refresh offset downwards
06704     case 0x97: // Snow line height
06705     case 0x99: // Global ID offset
06706       grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06707       break;
06708 
06709     case 0x9E: // Miscellaneous GRF features
06710       /* Set train list engine width */
06711       _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06712       /* Remove the local flags from the global flags */
06713       ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
06714 
06715       _misc_grf_features = res;
06716       break;
06717 
06718     case 0x9F: // locale-dependent settings
06719       grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06720       break;
06721 
06722     default:
06723       if (target < 0x80) {
06724         _cur.grffile->param[target] = res;
06725         /* param is zeroed by default */
06726         if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
06727       } else {
06728         grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06729       }
06730       break;
06731   }
06732 }
06733 
06734 /* Action 0x0E (GLS_SAFETYSCAN) */
06735 static void SafeGRFInhibit(ByteReader *buf)
06736 {
06737   /* <0E> <num> <grfids...>
06738    *
06739    * B num           Number of GRFIDs that follow
06740    * D grfids        GRFIDs of the files to deactivate */
06741 
06742   uint8 num = buf->ReadByte();
06743 
06744   for (uint i = 0; i < num; i++) {
06745     uint32 grfid = buf->ReadDWord();
06746 
06747     /* GRF is unsafe it if tries to deactivate other GRFs */
06748     if (grfid != _cur.grfconfig->ident.grfid) {
06749       SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06750 
06751       /* Skip remainder of GRF */
06752       _cur.skip_sprites = -1;
06753 
06754       return;
06755     }
06756   }
06757 }
06758 
06759 /* Action 0x0E */
06760 static void GRFInhibit(ByteReader *buf)
06761 {
06762   /* <0E> <num> <grfids...>
06763    *
06764    * B num           Number of GRFIDs that follow
06765    * D grfids        GRFIDs of the files to deactivate */
06766 
06767   uint8 num = buf->ReadByte();
06768 
06769   for (uint i = 0; i < num; i++) {
06770     uint32 grfid = buf->ReadDWord();
06771     GRFConfig *file = GetGRFConfig(grfid);
06772 
06773     /* Unset activation flag */
06774     if (file != NULL && file != _cur.grfconfig) {
06775       grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06776       GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06777       error->data = strdup(_cur.grfconfig->GetName());
06778     }
06779   }
06780 }
06781 
06783 static void FeatureTownName(ByteReader *buf)
06784 {
06785   /* <0F> <id> <style-name> <num-parts> <parts>
06786    *
06787    * B id          ID of this definition in bottom 7 bits (final definition if bit 7 set)
06788    * V style-name  Name of the style (only for final definition)
06789    * B num-parts   Number of parts in this definition
06790    * V parts       The parts */
06791 
06792   uint32 grfid = _cur.grffile->grfid;
06793 
06794   GRFTownName *townname = AddGRFTownName(grfid);
06795 
06796   byte id = buf->ReadByte();
06797   grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06798 
06799   if (HasBit(id, 7)) {
06800     /* Final definition */
06801     ClrBit(id, 7);
06802     bool new_scheme = _cur.grffile->grf_version >= 7;
06803 
06804     byte lang = buf->ReadByte();
06805 
06806     byte nb_gen = townname->nb_gen;
06807     do {
06808       ClrBit(lang, 7);
06809 
06810       const char *name = buf->ReadString();
06811 
06812       char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06813       grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06814       free(lang_name);
06815 
06816       townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06817 
06818       lang = buf->ReadByte();
06819     } while (lang != 0);
06820     townname->id[nb_gen] = id;
06821     townname->nb_gen++;
06822   }
06823 
06824   byte nb = buf->ReadByte();
06825   grfmsg(6, "FeatureTownName: %u parts", nb);
06826 
06827   townname->nbparts[id] = nb;
06828   townname->partlist[id] = CallocT<NamePartList>(nb);
06829 
06830   for (int i = 0; i < nb; i++) {
06831     byte nbtext =  buf->ReadByte();
06832     townname->partlist[id][i].bitstart  = buf->ReadByte();
06833     townname->partlist[id][i].bitcount  = buf->ReadByte();
06834     townname->partlist[id][i].maxprob   = 0;
06835     townname->partlist[id][i].partcount = nbtext;
06836     townname->partlist[id][i].parts     = CallocT<NamePart>(nbtext);
06837     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);
06838 
06839     for (int j = 0; j < nbtext; j++) {
06840       byte prob = buf->ReadByte();
06841 
06842       if (HasBit(prob, 7)) {
06843         byte ref_id = buf->ReadByte();
06844 
06845         if (townname->nbparts[ref_id] == 0) {
06846           grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06847           DelGRFTownName(grfid);
06848           DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06849           return;
06850         }
06851 
06852         grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06853         townname->partlist[id][i].parts[j].data.id = ref_id;
06854       } else {
06855         const char *text = buf->ReadString();
06856         townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06857         grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06858       }
06859       townname->partlist[id][i].parts[j].prob = prob;
06860       townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06861     }
06862     grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06863   }
06864 }
06865 
06867 static void DefineGotoLabel(ByteReader *buf)
06868 {
06869   /* <10> <label> [<comment>]
06870    *
06871    * B label      The label to define
06872    * V comment    Optional comment - ignored */
06873 
06874   byte nfo_label = buf->ReadByte();
06875 
06876   GRFLabel *label = MallocT<GRFLabel>(1);
06877   label->label    = nfo_label;
06878   label->nfo_line = _cur.nfo_line;
06879   label->pos      = FioGetPos();
06880   label->next     = NULL;
06881 
06882   /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
06883   if (_cur.grffile->label == NULL) {
06884     _cur.grffile->label = label;
06885   } else {
06886     /* Attach the label to the end of the list */
06887     GRFLabel *l;
06888     for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
06889     l->next = label;
06890   }
06891 
06892   grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06893 }
06894 
06899 static void ImportGRFSound(SoundEntry *sound)
06900 {
06901   const GRFFile *file;
06902   uint32 grfid = FioReadDword();
06903   SoundID sound_id = FioReadWord();
06904 
06905   file = GetFileByGRFID(grfid);
06906   if (file == NULL || file->sound_offset == 0) {
06907     grfmsg(1, "ImportGRFSound: Source file not available");
06908     return;
06909   }
06910 
06911   if (sound_id >= file->num_sounds) {
06912     grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06913     return;
06914   }
06915 
06916   grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06917 
06918   *sound = *GetSound(file->sound_offset + sound_id);
06919 
06920   /* Reset volume and priority, which TTDPatch doesn't copy */
06921   sound->volume   = 128;
06922   sound->priority = 0;
06923 }
06924 
06930 static void LoadGRFSound(size_t offs, SoundEntry *sound)
06931 {
06932   /* Set default volume and priority */
06933   sound->volume = 0x80;
06934   sound->priority = 0;
06935 
06936   if (offs != SIZE_MAX) {
06937     /* Sound is present in the NewGRF. */
06938     sound->file_slot = _cur.file_index;
06939     sound->file_offset = offs;
06940     sound->grf_container_ver = _cur.grf_container_ver;
06941   }
06942 }
06943 
06944 /* Action 0x11 */
06945 static void GRFSound(ByteReader *buf)
06946 {
06947   /* <11> <num>
06948    *
06949    * W num      Number of sound files that follow */
06950 
06951   uint16 num = buf->ReadWord();
06952   if (num == 0) return;
06953 
06954   SoundEntry *sound;
06955   if (_cur.grffile->sound_offset == 0) {
06956     _cur.grffile->sound_offset = GetNumSounds();
06957     _cur.grffile->num_sounds = num;
06958     sound = AllocateSound(num);
06959   } else {
06960     sound = GetSound(_cur.grffile->sound_offset);
06961   }
06962 
06963   for (int i = 0; i < num; i++) {
06964     _cur.nfo_line++;
06965 
06966     /* Check whether the index is in range. This might happen if multiple action 11 are present.
06967      * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
06968     bool invalid = i >= _cur.grffile->num_sounds;
06969 
06970     size_t offs = FioGetPos();
06971 
06972     uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
06973     byte type = FioReadByte();
06974 
06975     if (_cur.grf_container_ver >= 2 && type == 0xFD) {
06976       /* Reference to sprite section. */
06977       if (invalid) {
06978         grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06979         FioSkipBytes(len);
06980       } else if (len != 4) {
06981         grfmsg(1, "GRFSound: Invalid sprite section import");
06982         FioSkipBytes(len);
06983       } else {
06984         uint32 id = FioReadDword();
06985         if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
06986       }
06987       continue;
06988     }
06989 
06990     if (type != 0xFF) {
06991       grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
06992       FioSkipBytes(7);
06993       SkipSpriteData(type, len - 8);
06994       continue;
06995     }
06996 
06997     if (invalid) {
06998       grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06999       FioSkipBytes(len);
07000     }
07001 
07002     byte action = FioReadByte();
07003     switch (action) {
07004       case 0xFF:
07005         /* Allocate sound only in init stage. */
07006         if (_cur.stage == GLS_INIT) {
07007           if (_cur.grf_container_ver >= 2) {
07008             grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
07009           } else {
07010             LoadGRFSound(offs, sound + i);
07011           }
07012         }
07013         FioSkipBytes(len - 1); // already read <action>
07014         break;
07015 
07016       case 0xFE:
07017         if (_cur.stage == GLS_ACTIVATION) {
07018           /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
07019            * importing sounds, so this is probably all wrong... */
07020           if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
07021           ImportGRFSound(sound + i);
07022         } else {
07023           FioSkipBytes(len - 1); // already read <action>
07024         }
07025         break;
07026 
07027       default:
07028         grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
07029         FioSkipBytes(len - 1); // already read <action>
07030         break;
07031     }
07032   }
07033 }
07034 
07035 /* Action 0x11 (SKIP) */
07036 static void SkipAct11(ByteReader *buf)
07037 {
07038   /* <11> <num>
07039    *
07040    * W num      Number of sound files that follow */
07041 
07042   _cur.skip_sprites = buf->ReadWord();
07043 
07044   grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
07045 }
07046 
07048 static void LoadFontGlyph(ByteReader *buf)
07049 {
07050   /* <12> <num_def> <font_size> <num_char> <base_char>
07051    *
07052    * B num_def      Number of definitions
07053    * B font_size    Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
07054    * B num_char     Number of consecutive glyphs
07055    * W base_char    First character index */
07056 
07057   uint8 num_def = buf->ReadByte();
07058 
07059   for (uint i = 0; i < num_def; i++) {
07060     FontSize size    = (FontSize)buf->ReadByte();
07061     uint8  num_char  = buf->ReadByte();
07062     uint16 base_char = buf->ReadWord();
07063 
07064     if (size >= FS_END) {
07065       grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
07066     }
07067 
07068     grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
07069 
07070     for (uint c = 0; c < num_char; c++) {
07071       if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
07072       _cur.nfo_line++;
07073       LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
07074     }
07075   }
07076 }
07077 
07079 static void SkipAct12(ByteReader *buf)
07080 {
07081   /* <12> <num_def> <font_size> <num_char> <base_char>
07082    *
07083    * B num_def      Number of definitions
07084    * B font_size    Size of font (0 = normal, 1 = small, 2 = large)
07085    * B num_char     Number of consecutive glyphs
07086    * W base_char    First character index */
07087 
07088   uint8 num_def = buf->ReadByte();
07089 
07090   for (uint i = 0; i < num_def; i++) {
07091     /* Ignore 'size' byte */
07092     buf->ReadByte();
07093 
07094     /* Sum up number of characters */
07095     _cur.skip_sprites += buf->ReadByte();
07096 
07097     /* Ignore 'base_char' word */
07098     buf->ReadWord();
07099   }
07100 
07101   grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
07102 }
07103 
07105 static void TranslateGRFStrings(ByteReader *buf)
07106 {
07107   /* <13> <grfid> <num-ent> <offset> <text...>
07108    *
07109    * 4*B grfid     The GRFID of the file whose texts are to be translated
07110    * B   num-ent   Number of strings
07111    * W   offset    First text ID
07112    * S   text...   Zero-terminated strings */
07113 
07114   uint32 grfid = buf->ReadDWord();
07115   const GRFConfig *c = GetGRFConfig(grfid);
07116   if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
07117     grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
07118     return;
07119   }
07120 
07121   if (c->status == GCS_INITIALISED) {
07122     /* If the file is not active but will be activated later, give an error
07123      * and disable this file. */
07124     GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
07125 
07126     char tmp[256];
07127     GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
07128     error->data = strdup(tmp);
07129 
07130     return;
07131   }
07132 
07133   /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
07134    * to be added as a generic string, thus the language id of 0x7F. For this to work
07135    * new_scheme has to be true as well, which will also be implicitly the case for version 8
07136    * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
07137    * not change anything if a string has been provided specifically for this language. */
07138   byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
07139   byte num_strings = buf->ReadByte();
07140   uint16 first_id  = buf->ReadWord();
07141 
07142   if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
07143     grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
07144     return;
07145   }
07146 
07147   for (uint i = 0; i < num_strings && buf->HasData(); i++) {
07148     const char *string = buf->ReadString();
07149 
07150     if (StrEmpty(string)) {
07151       grfmsg(7, "TranslateGRFString: Ignoring empty string.");
07152       continue;
07153     }
07154 
07155     AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
07156   }
07157 }
07158 
07160 static bool ChangeGRFName(byte langid, const char *str)
07161 {
07162   AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
07163   return true;
07164 }
07165 
07167 static bool ChangeGRFDescription(byte langid, const char *str)
07168 {
07169   AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
07170   return true;
07171 }
07172 
07174 static bool ChangeGRFURL(byte langid, const char *str)
07175 {
07176   AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
07177   return true;
07178 }
07179 
07181 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
07182 {
07183   if (len != 1) {
07184     grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
07185     buf->Skip(len);
07186   } else {
07187     _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
07188   }
07189   return true;
07190 }
07191 
07193 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
07194 {
07195   if (len != 1) {
07196     grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
07197     buf->Skip(len);
07198   } else {
07199     char data = buf->ReadByte();
07200     GRFPalette pal = GRFP_GRF_UNSET;
07201     switch (data) {
07202       case '*':
07203       case 'A': pal = GRFP_GRF_ANY;     break;
07204       case 'W': pal = GRFP_GRF_WINDOWS; break;
07205       case 'D': pal = GRFP_GRF_DOS;     break;
07206       default:
07207         grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
07208         break;
07209     }
07210     if (pal != GRFP_GRF_UNSET) {
07211       _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
07212       _cur.grfconfig->palette |= pal;
07213     }
07214   }
07215   return true;
07216 }
07217 
07219 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
07220 {
07221   if (len != 1) {
07222     grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
07223     buf->Skip(len);
07224   } else {
07225     char data = buf->ReadByte();
07226     GRFPalette pal = GRFP_BLT_UNSET;
07227     switch (data) {
07228       case '8': pal = GRFP_BLT_UNSET; break;
07229       case '3': pal = GRFP_BLT_32BPP;  break;
07230       default:
07231         grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
07232         return true;
07233     }
07234     _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
07235     _cur.grfconfig->palette |= pal;
07236   }
07237   return true;
07238 }
07239 
07241 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
07242 {
07243   if (len != 4) {
07244     grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
07245     buf->Skip(len);
07246   } else {
07247     /* Set min_loadable_version as well (default to minimal compatibility) */
07248     _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07249   }
07250   return true;
07251 }
07252 
07254 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
07255 {
07256   if (len != 4) {
07257     grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
07258     buf->Skip(len);
07259   } else {
07260     _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07261     if (_cur.grfconfig->version == 0) {
07262       grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
07263       _cur.grfconfig->min_loadable_version = 0;
07264     }
07265     if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
07266       grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
07267       _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
07268     }
07269   }
07270   return true;
07271 }
07272 
07273 static GRFParameterInfo *_cur_parameter; 
07274 
07276 static bool ChangeGRFParamName(byte langid, const char *str)
07277 {
07278   AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
07279   return true;
07280 }
07281 
07283 static bool ChangeGRFParamDescription(byte langid, const char *str)
07284 {
07285   AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
07286   return true;
07287 }
07288 
07290 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
07291 {
07292   if (len != 1) {
07293     grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
07294     buf->Skip(len);
07295   } else {
07296     GRFParameterType type = (GRFParameterType)buf->ReadByte();
07297     if (type < PTYPE_END) {
07298       _cur_parameter->type = type;
07299     } else {
07300       grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
07301     }
07302   }
07303   return true;
07304 }
07305 
07307 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
07308 {
07309   if (_cur_parameter->type != PTYPE_UINT_ENUM) {
07310     grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
07311     buf->Skip(len);
07312   } else if (len != 8) {
07313     grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
07314     buf->Skip(len);
07315   } else {
07316     _cur_parameter->min_value = buf->ReadDWord();
07317     _cur_parameter->max_value = buf->ReadDWord();
07318   }
07319   return true;
07320 }
07321 
07323 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
07324 {
07325   if (len < 1 || len > 3) {
07326     grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
07327     buf->Skip(len);
07328   } else {
07329     byte param_nr = buf->ReadByte();
07330     if (param_nr >= lengthof(_cur.grfconfig->param)) {
07331       grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
07332       buf->Skip(len - 1);
07333     } else {
07334       _cur_parameter->param_nr = param_nr;
07335       if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
07336       if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
07337     }
07338   }
07339 
07340   return true;
07341 }
07342 
07344 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
07345 {
07346   if (len != 4) {
07347     grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
07348     buf->Skip(len);
07349   } else {
07350     _cur_parameter->def_value = buf->ReadDWord();
07351   }
07352   _cur.grfconfig->has_param_defaults = true;
07353   return true;
07354 }
07355 
07356 typedef bool (*DataHandler)(size_t, ByteReader *);  
07357 typedef bool (*TextHandler)(byte, const char *str); 
07358 typedef bool (*BranchHandler)(ByteReader *);        
07359 
07367 struct AllowedSubtags {
07369   AllowedSubtags() :
07370     id(0),
07371     type(0)
07372   {}
07373 
07379   AllowedSubtags(uint32 id, DataHandler handler) :
07380     id(id),
07381     type('B')
07382   {
07383     this->handler.data = handler;
07384   }
07385 
07391   AllowedSubtags(uint32 id, TextHandler handler) :
07392     id(id),
07393     type('T')
07394   {
07395     this->handler.text = handler;
07396   }
07397 
07403   AllowedSubtags(uint32 id, BranchHandler handler) :
07404     id(id),
07405     type('C')
07406   {
07407     this->handler.call_handler = true;
07408     this->handler.u.branch = handler;
07409   }
07410 
07416   AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
07417     id(id),
07418     type('C')
07419   {
07420     this->handler.call_handler = false;
07421     this->handler.u.subtags = subtags;
07422   }
07423 
07424   uint32 id; 
07425   byte type; 
07426   union {
07427     DataHandler data; 
07428     TextHandler text; 
07429     struct {
07430       union {
07431         BranchHandler branch;    
07432         AllowedSubtags *subtags; 
07433       } u;
07434       bool call_handler; 
07435     };
07436   } handler;
07437 };
07438 
07439 static bool SkipUnknownInfo(ByteReader *buf, byte type);
07440 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
07441 
07448 static bool ChangeGRFParamValueNames(ByteReader *buf)
07449 {
07450   byte type = buf->ReadByte();
07451   while (type != 0) {
07452     uint32 id = buf->ReadDWord();
07453     if (type != 'T' || id > _cur_parameter->max_value) {
07454       grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
07455       if (!SkipUnknownInfo(buf, type)) return false;
07456       type = buf->ReadByte();
07457       continue;
07458     }
07459 
07460     byte langid = buf->ReadByte();
07461     const char *name_string = buf->ReadString();
07462 
07463     SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
07464     if (val_name != _cur_parameter->value_names.End()) {
07465       AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
07466     } else {
07467       GRFText *list = NULL;
07468       AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
07469       _cur_parameter->value_names.Insert(id, list);
07470     }
07471 
07472     type = buf->ReadByte();
07473   }
07474   return true;
07475 }
07476 
07478 AllowedSubtags _tags_parameters[] = {
07479   AllowedSubtags('NAME', ChangeGRFParamName),
07480   AllowedSubtags('DESC', ChangeGRFParamDescription),
07481   AllowedSubtags('TYPE', ChangeGRFParamType),
07482   AllowedSubtags('LIMI', ChangeGRFParamLimits),
07483   AllowedSubtags('MASK', ChangeGRFParamMask),
07484   AllowedSubtags('VALU', ChangeGRFParamValueNames),
07485   AllowedSubtags('DFLT', ChangeGRFParamDefault),
07486   AllowedSubtags()
07487 };
07488 
07495 static bool HandleParameterInfo(ByteReader *buf)
07496 {
07497   byte type = buf->ReadByte();
07498   while (type != 0) {
07499     uint32 id = buf->ReadDWord();
07500     if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
07501       grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
07502       if (!SkipUnknownInfo(buf, type)) return false;
07503       type = buf->ReadByte();
07504       continue;
07505     }
07506 
07507     if (id >= _cur.grfconfig->param_info.Length()) {
07508       uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
07509       GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
07510       MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
07511     }
07512     if (_cur.grfconfig->param_info[id] == NULL) {
07513       _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
07514     }
07515     _cur_parameter = _cur.grfconfig->param_info[id];
07516     /* Read all parameter-data and process each node. */
07517     if (!HandleNodes(buf, _tags_parameters)) return false;
07518     type = buf->ReadByte();
07519   }
07520   return true;
07521 }
07522 
07524 AllowedSubtags _tags_info[] = {
07525   AllowedSubtags('NAME', ChangeGRFName),
07526   AllowedSubtags('DESC', ChangeGRFDescription),
07527   AllowedSubtags('URL_', ChangeGRFURL),
07528   AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
07529   AllowedSubtags('PALS', ChangeGRFPalette),
07530   AllowedSubtags('BLTR', ChangeGRFBlitter),
07531   AllowedSubtags('VRSN', ChangeGRFVersion),
07532   AllowedSubtags('MINV', ChangeGRFMinVersion),
07533   AllowedSubtags('PARA', HandleParameterInfo),
07534   AllowedSubtags()
07535 };
07536 
07538 AllowedSubtags _tags_root[] = {
07539   AllowedSubtags('INFO', _tags_info),
07540   AllowedSubtags()
07541 };
07542 
07543 
07550 static bool SkipUnknownInfo(ByteReader *buf, byte type)
07551 {
07552   /* type and id are already read */
07553   switch (type) {
07554     case 'C': {
07555       byte new_type = buf->ReadByte();
07556       while (new_type != 0) {
07557         buf->ReadDWord(); // skip the id
07558         if (!SkipUnknownInfo(buf, new_type)) return false;
07559         new_type = buf->ReadByte();
07560       }
07561       break;
07562     }
07563 
07564     case 'T':
07565       buf->ReadByte(); // lang
07566       buf->ReadString(); // actual text
07567       break;
07568 
07569     case 'B': {
07570       uint16 size = buf->ReadWord();
07571       buf->Skip(size);
07572       break;
07573     }
07574 
07575     default:
07576       return false;
07577   }
07578 
07579   return true;
07580 }
07581 
07590 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
07591 {
07592   uint i = 0;
07593   AllowedSubtags *tag;
07594   while ((tag = &subtags[i++])->type != 0) {
07595     if (tag->id != BSWAP32(id) || tag->type != type) continue;
07596     switch (type) {
07597       default: NOT_REACHED();
07598 
07599       case 'T': {
07600         byte langid = buf->ReadByte();
07601         return tag->handler.text(langid, buf->ReadString());
07602       }
07603 
07604       case 'B': {
07605         size_t len = buf->ReadWord();
07606         if (buf->Remaining() < len) return false;
07607         return tag->handler.data(len, buf);
07608       }
07609 
07610       case 'C': {
07611         if (tag->handler.call_handler) {
07612           return tag->handler.u.branch(buf);
07613         }
07614         return HandleNodes(buf, tag->handler.u.subtags);
07615       }
07616     }
07617   }
07618   grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
07619   return SkipUnknownInfo(buf, type);
07620 }
07621 
07628 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
07629 {
07630   byte type = buf->ReadByte();
07631   while (type != 0) {
07632     uint32 id = buf->ReadDWord();
07633     if (!HandleNode(type, id, buf, subtags)) return false;
07634     type = buf->ReadByte();
07635   }
07636   return true;
07637 }
07638 
07643 static void StaticGRFInfo(ByteReader *buf)
07644 {
07645   /* <14> <type> <id> <text/data...> */
07646   HandleNodes(buf, _tags_root);
07647 }
07648 
07654 static void GRFUnsafe(ByteReader *buf)
07655 {
07656   SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
07657 
07658   /* Skip remainder of GRF */
07659   _cur.skip_sprites = -1;
07660 }
07661 
07662 
07664 static void InitializeGRFSpecial()
07665 {
07666   _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)  // keepsmallairport
07667                      |                                                      (1 << 0x0D)  // newairports
07668                      |                                                      (1 << 0x0E)  // largestations
07669                      | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)  // longbridges
07670                      |                                                      (0 << 0x10)  // loadtime
07671                      |                                                      (1 << 0x12)  // presignals
07672                      |                                                      (1 << 0x13)  // extpresignals
07673                      | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)  // enginespersist
07674                      |                                                      (1 << 0x1B)  // multihead
07675                      |                                                      (1 << 0x1D)  // lowmemory
07676                      |                                                      (1 << 0x1E); // generalfixes
07677 
07678   _ttdpatch_flags[1] =   ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)  // moreairports - based on units of noise
07679                      |                                                      (1 << 0x08)  // mammothtrains
07680                      |                                                      (1 << 0x09)  // trainrefit
07681                      |                                                      (0 << 0x0B)  // subsidiaries
07682                      |         ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)  // gradualloading
07683                      |                                                      (1 << 0x12)  // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
07684                      |                                                      (1 << 0x13)  // unifiedmaglevmode - set bit 1 mode
07685                      |                                                      (1 << 0x14)  // bridgespeedlimits
07686                      |                                                      (1 << 0x16)  // eternalgame
07687                      |                                                      (1 << 0x17)  // newtrains
07688                      |                                                      (1 << 0x18)  // newrvs
07689                      |                                                      (1 << 0x19)  // newships
07690                      |                                                      (1 << 0x1A)  // newplanes
07691                      | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B)  // signalsontrafficside
07692                      |       ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
07693 
07694   _ttdpatch_flags[2] =                                                      (1 << 0x01)  // loadallgraphics - obsolote
07695                      |                                                      (1 << 0x03)  // semaphores
07696                      |                                                      (1 << 0x0A)  // newobjects
07697                      |                                                      (0 << 0x0B)  // enhancedgui
07698                      |                                                      (0 << 0x0C)  // newagerating
07699                      |  ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)  // buildonslopes
07700                      |                                                      (1 << 0x0E)  // fullloadany
07701                      |                                                      (1 << 0x0F)  // planespeed
07702                      |                                                      (0 << 0x10)  // moreindustriesperclimate - obsolete
07703                      |                                                      (0 << 0x11)  // moretoylandfeatures
07704                      |                                                      (1 << 0x12)  // newstations
07705                      |                                                      (1 << 0x13)  // tracktypecostdiff
07706                      |                                                      (1 << 0x14)  // manualconvert
07707                      |  ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)  // buildoncoasts
07708                      |                                                      (1 << 0x16)  // canals
07709                      |                                                      (1 << 0x17)  // newstartyear
07710                      |    ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)  // freighttrains
07711                      |                                                      (1 << 0x19)  // newhouses
07712                      |                                                      (1 << 0x1A)  // newbridges
07713                      |                                                      (1 << 0x1B)  // newtownnames
07714                      |                                                      (1 << 0x1C)  // moreanimation
07715                      |    ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)  // wagonspeedlimits
07716                      |                                                      (1 << 0x1E)  // newshistory
07717                      |                                                      (0 << 0x1F); // custombridgeheads
07718 
07719   _ttdpatch_flags[3] =                                                      (0 << 0x00)  // newcargodistribution
07720                      |                                                      (1 << 0x01)  // windowsnap
07721                      | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)  // townbuildnoroad
07722                      |                                                      (1 << 0x03)  // pathbasedsignalling
07723                      |                                                      (0 << 0x04)  // aichoosechance
07724                      |                                                      (1 << 0x05)  // resolutionwidth
07725                      |                                                      (1 << 0x06)  // resolutionheight
07726                      |                                                      (1 << 0x07)  // newindustries
07727                      |           ((_settings_game.order.improved_load ? 1 : 0) << 0x08)  // fifoloading
07728                      |                                                      (0 << 0x09)  // townroadbranchprob
07729                      |                                                      (0 << 0x0A)  // tempsnowline
07730                      |                                                      (1 << 0x0B)  // newcargo
07731                      |                                                      (1 << 0x0C)  // enhancemultiplayer
07732                      |                                                      (1 << 0x0D)  // onewayroads
07733                      |                                                      (1 << 0x0E)  // irregularstations
07734                      |                                                      (1 << 0x0F)  // statistics
07735                      |                                                      (1 << 0x10)  // newsounds
07736                      |                                                      (1 << 0x11)  // autoreplace
07737                      |                                                      (1 << 0x12)  // autoslope
07738                      |                                                      (0 << 0x13)  // followvehicle
07739                      |                                                      (1 << 0x14)  // trams
07740                      |                                                      (0 << 0x15)  // enhancetunnels
07741                      |                                                      (1 << 0x16)  // shortrvs
07742                      |                                                      (1 << 0x17)  // articulatedrvs
07743                      |       ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)  // dynamic engines
07744                      |                                                      (1 << 0x1E)  // variablerunningcosts
07745                      |                                                      (1 << 0x1F); // any switch is on
07746 }
07747 
07749 static void ResetCustomStations()
07750 {
07751   const GRFFile * const *end = _grf_files.End();
07752   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07753     StationSpec **&stations = (*file)->stations;
07754     if (stations == NULL) continue;
07755     for (uint i = 0; i < MAX_STATIONS; i++) {
07756       if (stations[i] == NULL) continue;
07757       StationSpec *statspec = stations[i];
07758 
07759       delete[] statspec->renderdata;
07760 
07761       /* Release platforms and layouts */
07762       if (!statspec->copied_layouts) {
07763         for (uint l = 0; l < statspec->lengths; l++) {
07764           for (uint p = 0; p < statspec->platforms[l]; p++) {
07765             free(statspec->layouts[l][p]);
07766           }
07767           free(statspec->layouts[l]);
07768         }
07769         free(statspec->layouts);
07770         free(statspec->platforms);
07771       }
07772 
07773       /* Release this station */
07774       free(statspec);
07775     }
07776 
07777     /* Free and reset the station data */
07778     free(stations);
07779     stations = NULL;
07780   }
07781 }
07782 
07784 static void ResetCustomHouses()
07785 {
07786   const GRFFile * const *end = _grf_files.End();
07787   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07788     HouseSpec **&housespec = (*file)->housespec;
07789     if (housespec == NULL) continue;
07790     for (uint i = 0; i < HOUSE_MAX; i++) {
07791       free(housespec[i]);
07792     }
07793 
07794     free(housespec);
07795     housespec = NULL;
07796   }
07797 }
07798 
07800 static void ResetCustomAirports()
07801 {
07802   const GRFFile * const *end = _grf_files.End();
07803   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07804     AirportSpec **aslist = (*file)->airportspec;
07805     if (aslist != NULL) {
07806       for (uint i = 0; i < NUM_AIRPORTS; i++) {
07807         AirportSpec *as = aslist[i];
07808 
07809         if (as != NULL) {
07810           /* We need to remove the tiles layouts */
07811           for (int j = 0; j < as->num_table; j++) {
07812             /* remove the individual layouts */
07813             free(as->table[j]);
07814           }
07815           free(as->table);
07816           free(as->depot_table);
07817 
07818           free(as);
07819         }
07820       }
07821       free(aslist);
07822       (*file)->airportspec = NULL;
07823     }
07824 
07825     AirportTileSpec **&airporttilespec = (*file)->airtspec;
07826     if (airporttilespec != NULL) {
07827       for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07828         free(airporttilespec[i]);
07829       }
07830       free(airporttilespec);
07831       airporttilespec = NULL;
07832     }
07833   }
07834 }
07835 
07837 static void ResetCustomIndustries()
07838 {
07839   const GRFFile * const *end = _grf_files.End();
07840   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07841     IndustrySpec **&industryspec = (*file)->industryspec;
07842     IndustryTileSpec **&indtspec = (*file)->indtspec;
07843 
07844     /* We are verifiying both tiles and industries specs loaded from the grf file
07845      * First, let's deal with industryspec */
07846     if (industryspec != NULL) {
07847       for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07848         IndustrySpec *ind = industryspec[i];
07849         if (ind == NULL) continue;
07850 
07851         /* We need to remove the sounds array */
07852         if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07853           free(ind->random_sounds);
07854         }
07855 
07856         /* We need to remove the tiles layouts */
07857         CleanIndustryTileTable(ind);
07858 
07859         free(ind);
07860       }
07861 
07862       free(industryspec);
07863       industryspec = NULL;
07864     }
07865 
07866     if (indtspec == NULL) continue;
07867     for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07868       free(indtspec[i]);
07869     }
07870 
07871     free(indtspec);
07872     indtspec = NULL;
07873   }
07874 }
07875 
07877 static void ResetCustomObjects()
07878 {
07879   const GRFFile * const *end = _grf_files.End();
07880   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07881     ObjectSpec **&objectspec = (*file)->objectspec;
07882     if (objectspec == NULL) continue;
07883     for (uint i = 0; i < NUM_OBJECTS; i++) {
07884       free(objectspec[i]);
07885     }
07886 
07887     free(objectspec);
07888     objectspec = NULL;
07889   }
07890 }
07891 
07893 static void ResetNewGRF()
07894 {
07895   const GRFFile * const *end = _grf_files.End();
07896   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07897     delete *file;
07898   }
07899 
07900   _grf_files.Clear();
07901   _cur.grffile   = NULL;
07902 }
07903 
07905 static void ResetNewGRFErrors()
07906 {
07907   for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07908     if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07909       delete c->error;
07910       c->error = NULL;
07911     }
07912   }
07913 }
07914 
07919 void ResetNewGRFData()
07920 {
07921   CleanUpStrings();
07922   CleanUpGRFTownNames();
07923 
07924   /* Copy/reset original engine info data */
07925   SetupEngines();
07926 
07927   /* Copy/reset original bridge info data */
07928   ResetBridges();
07929 
07930   /* Reset rail type information */
07931   ResetRailTypes();
07932 
07933   /* Allocate temporary refit/cargo class data */
07934   _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07935 
07936   /* Fill rail type label temporary data for default trains */
07937   Engine *e;
07938   FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07939     _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07940   }
07941 
07942   /* Reset GRM reservations */
07943   memset(&_grm_engines, 0, sizeof(_grm_engines));
07944   memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
07945 
07946   /* Reset generic feature callback lists */
07947   ResetGenericCallbacks();
07948 
07949   /* Reset price base data */
07950   ResetPriceBaseMultipliers();
07951 
07952   /* Reset the curencies array */
07953   ResetCurrencies();
07954 
07955   /* Reset the house array */
07956   ResetCustomHouses();
07957   ResetHouses();
07958 
07959   /* Reset the industries structures*/
07960   ResetCustomIndustries();
07961   ResetIndustries();
07962 
07963   /* Reset the objects. */
07964   ObjectClass::Reset();
07965   ResetCustomObjects();
07966   ResetObjects();
07967 
07968   /* Reset station classes */
07969   StationClass::Reset();
07970   ResetCustomStations();
07971 
07972   /* Reset airport-related structures */
07973   AirportClass::Reset();
07974   ResetCustomAirports();
07975   AirportSpec::ResetAirports();
07976   AirportTileSpec::ResetAirportTiles();
07977 
07978   /* Reset canal sprite groups and flags */
07979   memset(_water_feature, 0, sizeof(_water_feature));
07980 
07981   /* Reset the snowline table. */
07982   ClearSnowLine();
07983 
07984   /* Reset NewGRF files */
07985   ResetNewGRF();
07986 
07987   /* Reset NewGRF errors. */
07988   ResetNewGRFErrors();
07989 
07990   /* Set up the default cargo types */
07991   SetupCargoForClimate(_settings_game.game_creation.landscape);
07992 
07993   /* Reset misc GRF features and train list display variables */
07994   _misc_grf_features = 0;
07995 
07996   _loaded_newgrf_features.has_2CC           = false;
07997   _loaded_newgrf_features.used_liveries     = 1 << LS_DEFAULT;
07998   _loaded_newgrf_features.has_newhouses     = false;
07999   _loaded_newgrf_features.has_newindustries = false;
08000   _loaded_newgrf_features.shore             = SHORE_REPLACE_NONE;
08001 
08002   /* Clear all GRF overrides */
08003   _grf_id_overrides.clear();
08004 
08005   InitializeSoundPool();
08006   _spritegroup_pool.CleanPool();
08007 }
08008 
08012 void ResetPersistentNewGRFData()
08013 {
08014   /* Reset override managers */
08015   _engine_mngr.ResetToDefaultMapping();
08016   _house_mngr.ResetMapping();
08017   _industry_mngr.ResetMapping();
08018   _industile_mngr.ResetMapping();
08019   _airport_mngr.ResetMapping();
08020   _airporttile_mngr.ResetMapping();
08021 }
08022 
08027 static void BuildCargoTranslationMap()
08028 {
08029   memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
08030 
08031   for (CargoID c = 0; c < NUM_CARGO; c++) {
08032     const CargoSpec *cs = CargoSpec::Get(c);
08033     if (!cs->IsValid()) continue;
08034 
08035     if (_cur.grffile->cargo_list.Length() == 0) {
08036       /* Default translation table, so just a straight mapping to bitnum */
08037       _cur.grffile->cargo_map[c] = cs->bitnum;
08038     } else {
08039       /* Check the translation table for this cargo's label */
08040       int index = _cur.grffile->cargo_list.FindIndex(cs->label);
08041       if (index >= 0) _cur.grffile->cargo_map[c] = index;
08042     }
08043   }
08044 }
08045 
08050 static void InitNewGRFFile(const GRFConfig *config)
08051 {
08052   GRFFile *newfile = GetFileByFilename(config->filename);
08053   if (newfile != NULL) {
08054     /* We already loaded it once. */
08055     _cur.grffile = newfile;
08056     return;
08057   }
08058 
08059   newfile = new GRFFile(config);
08060   *_grf_files.Append() = _cur.grffile = newfile;
08061 }
08062 
08067 GRFFile::GRFFile(const GRFConfig *config)
08068 {
08069   this->filename = strdup(config->filename);
08070   this->grfid = config->ident.grfid;
08071 
08072   /* Initialise local settings to defaults */
08073   this->traininfo_vehicle_pitch = 0;
08074   this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
08075 
08076   /* Mark price_base_multipliers as 'not set' */
08077   for (Price i = PR_BEGIN; i < PR_END; i++) {
08078     this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
08079   }
08080 
08081   /* Initialise rail type map with default rail types */
08082   memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
08083   this->railtype_map[0] = RAILTYPE_RAIL;
08084   this->railtype_map[1] = RAILTYPE_ELECTRIC;
08085   this->railtype_map[2] = RAILTYPE_MONO;
08086   this->railtype_map[3] = RAILTYPE_MAGLEV;
08087 
08088   /* Copy the initial parameter list
08089    * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
08090   assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
08091 
08092   assert(config->num_params <= lengthof(config->param));
08093   this->param_end = config->num_params;
08094   if (this->param_end > 0) {
08095     MemCpyT(this->param, config->param, this->param_end);
08096   }
08097 }
08098 
08099 GRFFile::~GRFFile()
08100 {
08101   free(this->filename);
08102   delete[] this->language_map;
08103 }
08104 
08105 
08110 static const CargoLabel _default_refitmasks_rail[] = {
08111   'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
08112   'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
08113   'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08114   'PLST', 'FZDR',
08115   0 };
08116 
08117 static const CargoLabel _default_refitmasks_road[] = {
08118   0 };
08119 
08120 static const CargoLabel _default_refitmasks_ships[] = {
08121   'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
08122   'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
08123   'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08124   'PLST', 'FZDR',
08125   0 };
08126 
08127 static const CargoLabel _default_refitmasks_aircraft[] = {
08128   'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
08129   'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
08130   0 };
08131 
08132 static const CargoLabel * const _default_refitmasks[] = {
08133   _default_refitmasks_rail,
08134   _default_refitmasks_road,
08135   _default_refitmasks_ships,
08136   _default_refitmasks_aircraft,
08137 };
08138 
08139 
08143 static void CalculateRefitMasks()
08144 {
08145   Engine *e;
08146 
08147   FOR_ALL_ENGINES(e) {
08148     EngineID engine = e->index;
08149     EngineInfo *ei = &e->info;
08150     bool only_defaultcargo; 
08151 
08152     /* Did the newgrf specify any refitting? If not, use defaults. */
08153     if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
08154       uint32 mask = 0;
08155       uint32 not_mask = 0;
08156       uint32 xor_mask = ei->refit_mask;
08157 
08158       /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
08159        * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
08160       only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
08161 
08162       if (_gted[engine].cargo_allowed != 0) {
08163         /* Build up the list of cargo types from the set cargo classes. */
08164         const CargoSpec *cs;
08165         FOR_ALL_CARGOSPECS(cs) {
08166           if (_gted[engine].cargo_allowed    & cs->classes) SetBit(mask,     cs->Index());
08167           if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
08168         }
08169       }
08170 
08171       ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
08172 
08173       /* Apply explicit refit includes/excludes. */
08174       ei->refit_mask |= _gted[engine].ctt_include_mask;
08175       ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
08176     } else {
08177       uint32 xor_mask = 0;
08178 
08179       /* Don't apply default refit mask to wagons nor engines with no capacity */
08180       if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
08181         const CargoLabel *cl = _default_refitmasks[e->type];
08182         for (uint i = 0;; i++) {
08183           if (cl[i] == 0) break;
08184 
08185           CargoID cargo = GetCargoIDByLabel(cl[i]);
08186           if (cargo == CT_INVALID) continue;
08187 
08188           SetBit(xor_mask, cargo);
08189         }
08190       }
08191 
08192       ei->refit_mask = xor_mask & _cargo_mask;
08193 
08194       /* If the mask is zero, the vehicle shall only carry the default cargo */
08195       only_defaultcargo = (ei->refit_mask == 0);
08196     }
08197 
08198     /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
08199     if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
08200 
08201     /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
08202      * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
08203     if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
08204       ei->cargo_type = CT_INVALID;
08205     }
08206 
08207     /* Check if this engine's cargo type is valid. If not, set to the first refittable
08208      * cargo type. Finally disable the vehicle, if there is still no cargo. */
08209     if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
08210       /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
08211       const uint8 *cargo_map_for_first_refittable = NULL;
08212       {
08213         const GRFFile *file = _gted[engine].defaultcargo_grf;
08214         if (file == NULL) file = e->GetGRF();
08215         if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
08216           cargo_map_for_first_refittable = file->cargo_map;
08217         }
08218       }
08219 
08220       if (cargo_map_for_first_refittable != NULL) {
08221         /* Use first refittable cargo from cargo translation table */
08222         byte best_local_slot = 0xFF;
08223         CargoID cargo_type;
08224         FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
08225           byte local_slot = cargo_map_for_first_refittable[cargo_type];
08226           if (local_slot < best_local_slot) {
08227             best_local_slot = local_slot;
08228             ei->cargo_type = cargo_type;
08229           }
08230         }
08231       }
08232 
08233       if (ei->cargo_type == CT_INVALID) {
08234         /* Use first refittable cargo slot */
08235         ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
08236       }
08237     }
08238     if (ei->cargo_type == CT_INVALID) ei->climates = 0;
08239 
08240     /* Clear refit_mask for not refittable ships */
08241     if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
08242       ei->refit_mask = 0;
08243     }
08244   }
08245 }
08246 
08248 static void FinaliseCanals()
08249 {
08250   for (uint i = 0; i < CF_END; i++) {
08251     if (_water_feature[i].grffile != NULL) {
08252       _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
08253       _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
08254     }
08255   }
08256 }
08257 
08259 static void FinaliseEngineArray()
08260 {
08261   Engine *e;
08262 
08263   FOR_ALL_ENGINES(e) {
08264     if (e->GetGRF() == NULL) {
08265       const EngineIDMapping &eid = _engine_mngr[e->index];
08266       if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
08267         e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
08268       }
08269     }
08270 
08271     /* When the train does not set property 27 (misc flags), but it
08272      * is overridden by a NewGRF graphically we want to disable the
08273      * flipping possibility. */
08274     if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
08275       ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
08276     }
08277 
08278     /* Skip wagons, there livery is defined via the engine */
08279     if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
08280       LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
08281       SetBit(_loaded_newgrf_features.used_liveries, ls);
08282       /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
08283 
08284       if (e->type == VEH_TRAIN) {
08285         SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
08286         switch (ls) {
08287           case LS_STEAM:
08288           case LS_DIESEL:
08289           case LS_ELECTRIC:
08290           case LS_MONORAIL:
08291           case LS_MAGLEV:
08292             SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
08293             break;
08294 
08295           case LS_DMU:
08296           case LS_EMU:
08297             SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
08298             break;
08299 
08300           default: NOT_REACHED();
08301         }
08302       }
08303     }
08304   }
08305 }
08306 
08308 static void FinaliseCargoArray()
08309 {
08310   for (CargoID c = 0; c < NUM_CARGO; c++) {
08311     CargoSpec *cs = CargoSpec::Get(c);
08312     if (!cs->IsValid()) {
08313       cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
08314       cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
08315       cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
08316     }
08317   }
08318 }
08319 
08331 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
08332 {
08333   if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
08334         (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
08335       ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
08336         (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
08337         next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
08338     hs->enabled = false;
08339     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);
08340     return false;
08341   }
08342 
08343   /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
08344    * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
08345    * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
08346   if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
08347       ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
08348     hs->enabled = false;
08349     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);
08350     return false;
08351   }
08352 
08353   /* Substitute type is also used for override, and having an override with a different size causes crashes.
08354    * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
08355   if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
08356     hs->enabled = false;
08357     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);
08358     return false;
08359   }
08360 
08361   /* Make sure that additional parts of multitile houses are not available. */
08362   if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
08363     hs->enabled = false;
08364     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);
08365     return false;
08366   }
08367 
08368   return true;
08369 }
08370 
08377 static void EnsureEarlyHouse(HouseZones bitmask)
08378 {
08379   Year min_year = MAX_YEAR;
08380 
08381   for (int i = 0; i < HOUSE_MAX; i++) {
08382     HouseSpec *hs = HouseSpec::Get(i);
08383     if (hs == NULL || !hs->enabled) continue;
08384     if ((hs->building_availability & bitmask) != bitmask) continue;
08385     if (hs->min_year < min_year) min_year = hs->min_year;
08386   }
08387 
08388   if (min_year == 0) return;
08389 
08390   for (int i = 0; i < HOUSE_MAX; i++) {
08391     HouseSpec *hs = HouseSpec::Get(i);
08392     if (hs == NULL || !hs->enabled) continue;
08393     if ((hs->building_availability & bitmask) != bitmask) continue;
08394     if (hs->min_year == min_year) hs->min_year = 0;
08395   }
08396 }
08397 
08404 static void FinaliseHouseArray()
08405 {
08406   /* If there are no houses with start dates before 1930, then all houses
08407    * with start dates of 1930 have them reset to 0. This is in order to be
08408    * compatible with TTDPatch, where if no houses have start dates before
08409    * 1930 and the date is before 1930, the game pretends that this is 1930.
08410    * If there have been any houses defined with start dates before 1930 then
08411    * the dates are left alone.
08412    * On the other hand, why 1930? Just 'fix' the houses with the lowest
08413    * minimum introduction date to 0.
08414    */
08415   const GRFFile * const *end = _grf_files.End();
08416   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08417     HouseSpec **&housespec = (*file)->housespec;
08418     if (housespec == NULL) continue;
08419 
08420     for (int i = 0; i < HOUSE_MAX; i++) {
08421       HouseSpec *hs = housespec[i];
08422 
08423       if (hs == NULL) continue;
08424 
08425       const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
08426       const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
08427       const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
08428 
08429       if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
08430 
08431       _house_mngr.SetEntitySpec(hs);
08432     }
08433   }
08434 
08435   for (int i = 0; i < HOUSE_MAX; i++) {
08436     HouseSpec *hs = HouseSpec::Get(i);
08437     const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
08438     const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
08439     const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
08440 
08441     /* We need to check all houses again to we are sure that multitile houses
08442      * did get consecutive IDs and none of the parts are missing. */
08443     if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
08444       /* GetHouseNorthPart checks 3 houses that are directly before
08445        * it in the house pool. If any of those houses have multi-tile
08446        * flags set it assumes it's part of a multitile house. Since
08447        * we can have invalid houses in the pool marked as disabled, we
08448        * don't want to have them influencing valid tiles. As such set
08449        * building_flags to zero here to make sure any house following
08450        * this one in the pool is properly handled as 1x1 house. */
08451       hs->building_flags = TILE_NO_FLAG;
08452     }
08453   }
08454 
08455   HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
08456   EnsureEarlyHouse(HZ_ZON1 | climate_mask);
08457   EnsureEarlyHouse(HZ_ZON2 | climate_mask);
08458   EnsureEarlyHouse(HZ_ZON3 | climate_mask);
08459   EnsureEarlyHouse(HZ_ZON4 | climate_mask);
08460   EnsureEarlyHouse(HZ_ZON5 | climate_mask);
08461 
08462   if (_settings_game.game_creation.landscape == LT_ARCTIC) {
08463     EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
08464     EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
08465     EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
08466     EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
08467     EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
08468   }
08469 }
08470 
08476 static void FinaliseIndustriesArray()
08477 {
08478   const GRFFile * const *end = _grf_files.End();
08479   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08480     IndustrySpec **&industryspec = (*file)->industryspec;
08481     IndustryTileSpec **&indtspec = (*file)->indtspec;
08482     if (industryspec != NULL) {
08483       for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
08484         IndustrySpec *indsp = industryspec[i];
08485 
08486         if (indsp != NULL && indsp->enabled) {
08487           StringID strid;
08488           /* process the conversion of text at the end, so to be sure everything will be fine
08489            * and available.  Check if it does not return undefind marker, which is a very good sign of a
08490            * substitute industry who has not changed the string been examined, thus using it as such */
08491           strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
08492           if (strid != STR_UNDEFINED) indsp->name = strid;
08493 
08494           strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
08495           if (strid != STR_UNDEFINED) indsp->closure_text = strid;
08496 
08497           strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
08498           if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
08499 
08500           strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
08501           if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
08502 
08503           strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
08504           if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
08505 
08506           if (indsp->station_name != STR_NULL) {
08507             /* STR_NULL (0) can be set by grf.  It has a meaning regarding assignation of the
08508              * station's name. Don't want to lose the value, therefore, do not process. */
08509             strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
08510             if (strid != STR_UNDEFINED) indsp->station_name = strid;
08511           }
08512 
08513           _industry_mngr.SetEntitySpec(indsp);
08514           _loaded_newgrf_features.has_newindustries = true;
08515         }
08516       }
08517     }
08518 
08519     if (indtspec != NULL) {
08520       for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
08521         IndustryTileSpec *indtsp = indtspec[i];
08522         if (indtsp != NULL) {
08523           _industile_mngr.SetEntitySpec(indtsp);
08524         }
08525       }
08526     }
08527   }
08528 
08529   for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
08530     IndustrySpec *indsp = &_industry_specs[j];
08531     if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
08532       for (uint i = 0; i < 3; i++) {
08533         indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
08534       }
08535     }
08536     if (!indsp->enabled) {
08537       indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
08538     }
08539   }
08540 }
08541 
08547 static void FinaliseObjectsArray()
08548 {
08549   const GRFFile * const *end = _grf_files.End();
08550   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08551     ObjectSpec **&objectspec = (*file)->objectspec;
08552     if (objectspec != NULL) {
08553       for (int i = 0; i < NUM_OBJECTS; i++) {
08554         if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
08555           _object_mngr.SetEntitySpec(objectspec[i]);
08556         }
08557       }
08558     }
08559   }
08560 }
08561 
08567 static void FinaliseAirportsArray()
08568 {
08569   const GRFFile * const *end = _grf_files.End();
08570   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08571     AirportSpec **&airportspec = (*file)->airportspec;
08572     if (airportspec != NULL) {
08573       for (int i = 0; i < NUM_AIRPORTS; i++) {
08574         if (airportspec[i] != NULL && airportspec[i]->enabled) {
08575           _airport_mngr.SetEntitySpec(airportspec[i]);
08576         }
08577       }
08578     }
08579 
08580     AirportTileSpec **&airporttilespec = (*file)->airtspec;
08581     if (airporttilespec != NULL) {
08582       for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
08583         if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
08584           _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
08585         }
08586       }
08587     }
08588   }
08589 }
08590 
08591 /* Here we perform initial decoding of some special sprites (as are they
08592  * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
08593  * partial implementation yet).
08594  * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
08595  * a crafted invalid GRF file. We should tell that to the user somehow, or
08596  * better make this more robust in the future. */
08597 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
08598 {
08599   /* XXX: There is a difference between staged loading in TTDPatch and
08600    * here.  In TTDPatch, for some reason actions 1 and 2 are carried out
08601    * during stage 1, whilst action 3 is carried out during stage 2 (to
08602    * "resolve" cargo IDs... wtf). This is a little problem, because cargo
08603    * IDs are valid only within a given set (action 1) block, and may be
08604    * overwritten after action 3 associates them. But overwriting happens
08605    * in an earlier stage than associating, so...  We just process actions
08606    * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
08607    * --pasky
08608    * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
08609    * is not in memory and scanning the file every time would be too expensive.
08610    * In other stages we skip action 0x10 since it's already dealt with. */
08611   static const SpecialSpriteHandler handlers[][GLS_END] = {
08612     /* 0x00 */ { NULL,     SafeChangeInfo, NULL,       NULL,           ReserveChangeInfo, FeatureChangeInfo, },
08613     /* 0x01 */ { SkipAct1, SkipAct1,  SkipAct1,        SkipAct1,       SkipAct1,          NewSpriteSet, },
08614     /* 0x02 */ { NULL,     NULL,      NULL,            NULL,           NULL,              NewSpriteGroup, },
08615     /* 0x03 */ { NULL,     GRFUnsafe, NULL,            NULL,           NULL,              FeatureMapSpriteGroup, },
08616     /* 0x04 */ { NULL,     NULL,      NULL,            NULL,           NULL,              FeatureNewName, },
08617     /* 0x05 */ { SkipAct5, SkipAct5,  SkipAct5,        SkipAct5,       SkipAct5,          GraphicsNew, },
08618     /* 0x06 */ { NULL,     NULL,      NULL,            CfgApply,       CfgApply,          CfgApply, },
08619     /* 0x07 */ { NULL,     NULL,      NULL,            NULL,           SkipIf,            SkipIf, },
08620     /* 0x08 */ { ScanInfo, NULL,      NULL,            GRFInfo,        GRFInfo,           GRFInfo, },
08621     /* 0x09 */ { NULL,     NULL,      NULL,            SkipIf,         SkipIf,            SkipIf, },
08622     /* 0x0A */ { SkipActA, SkipActA,  SkipActA,        SkipActA,       SkipActA,          SpriteReplace, },
08623     /* 0x0B */ { NULL,     NULL,      NULL,            GRFLoadError,   GRFLoadError,      GRFLoadError, },
08624     /* 0x0C */ { NULL,     NULL,      NULL,            GRFComment,     NULL,              GRFComment, },
08625     /* 0x0D */ { NULL,     SafeParamSet, NULL,         ParamSet,       ParamSet,          ParamSet, },
08626     /* 0x0E */ { NULL,     SafeGRFInhibit, NULL,       GRFInhibit,     GRFInhibit,        GRFInhibit, },
08627     /* 0x0F */ { NULL,     GRFUnsafe, NULL,            FeatureTownName, NULL,             NULL, },
08628     /* 0x10 */ { NULL,     NULL,      DefineGotoLabel, NULL,           NULL,              NULL, },
08629     /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11,       GRFSound,       SkipAct11,         GRFSound, },
08630     /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12,      SkipAct12,      SkipAct12,         LoadFontGlyph, },
08631     /* 0x13 */ { NULL,     NULL,      NULL,            NULL,           NULL,              TranslateGRFStrings, },
08632     /* 0x14 */ { StaticGRFInfo, NULL, NULL,            NULL,           NULL,              NULL, },
08633   };
08634 
08635   GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
08636 
08637   GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
08638   if (it == _grf_line_to_action6_sprite_override.end()) {
08639     /* No preloaded sprite to work with; read the
08640      * pseudo sprite content. */
08641     FioReadBlock(buf, num);
08642   } else {
08643     /* Use the preloaded sprite data. */
08644     buf = _grf_line_to_action6_sprite_override[location];
08645     grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
08646 
08647     /* Skip the real (original) content of this action. */
08648     FioSeekTo(num, SEEK_CUR);
08649   }
08650 
08651   ByteReader br(buf, buf + num);
08652   ByteReader *bufp = &br;
08653 
08654   try {
08655     byte action = bufp->ReadByte();
08656 
08657     if (action == 0xFF) {
08658       grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
08659     } else if (action == 0xFE) {
08660       grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
08661     } else if (action >= lengthof(handlers)) {
08662       grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
08663     } else if (handlers[action][stage] == NULL) {
08664       grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
08665     } else {
08666       grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
08667       handlers[action][stage](bufp);
08668     }
08669   } catch (...) {
08670     grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
08671     DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
08672   }
08673 }
08674 
08675 
08677 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
08678 
08683 byte GetGRFContainerVersion()
08684 {
08685   size_t pos = FioGetPos();
08686 
08687   if (FioReadWord() == 0) {
08688     /* Check for GRF container version 2, which is identified by the bytes
08689      * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
08690     for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
08691       if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
08692     }
08693 
08694     return 2;
08695   }
08696 
08697   /* Container version 1 has no header, rewind to start. */
08698   FioSeekTo(pos, SEEK_SET);
08699   return 1;
08700 }
08701 
08709 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
08710 {
08711   const char *filename = config->filename;
08712 
08713   /* A .grf file is activated only if it was active when the game was
08714    * started.  If a game is loaded, only its active .grfs will be
08715    * reactivated, unless "loadallgraphics on" is used.  A .grf file is
08716    * considered active if its action 8 has been processed, i.e. its
08717    * action 8 hasn't been skipped using an action 7.
08718    *
08719    * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
08720    * carried out.  All others are ignored, because they only need to be
08721    * processed once at initialization.  */
08722   if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
08723     _cur.grffile = GetFileByFilename(filename);
08724     if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
08725     if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
08726     if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
08727     _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
08728   }
08729 
08730   if (file_index > LAST_GRF_SLOT) {
08731     DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
08732     config->status = GCS_DISABLED;
08733     config->error  = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
08734     return;
08735   }
08736 
08737   FioOpenFile(file_index, filename, subdir);
08738   _cur.file_index = file_index; // XXX
08739   _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
08740 
08741   _cur.grfconfig = config;
08742 
08743   DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
08744 
08745   _cur.grf_container_ver = GetGRFContainerVersion();
08746   if (_cur.grf_container_ver == 0) {
08747     DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08748     return;
08749   }
08750 
08751   if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
08752     /* We need the sprite offsets in the init stage for NewGRF sounds
08753      * and in the activation stage for real sprites. */
08754     ReadGRFSpriteOffsets(_cur.grf_container_ver);
08755   } else {
08756     /* Skip sprite section offset if present. */
08757     if (_cur.grf_container_ver >= 2) FioReadDword();
08758   }
08759 
08760   if (_cur.grf_container_ver >= 2) {
08761     /* Read compression value. */
08762     byte compression = FioReadByte();
08763     if (compression != 0) {
08764       DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
08765       return;
08766     }
08767   }
08768 
08769   /* Skip the first sprite; we don't care about how many sprites this
08770    * does contain; newest TTDPatches and George's longvehicles don't
08771    * neither, apparently. */
08772   uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
08773   if (num == 4 && FioReadByte() == 0xFF) {
08774     FioReadDword();
08775   } else {
08776     DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08777     return;
08778   }
08779 
08780   _cur.ClearDataForNextFile();
08781 
08782   ReusableBuffer<byte> buf;
08783 
08784   while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
08785     byte type = FioReadByte();
08786     _cur.nfo_line++;
08787 
08788     if (type == 0xFF) {
08789       if (_cur.skip_sprites == 0) {
08790         DecodeSpecialSprite(buf.Allocate(num), num, stage);
08791 
08792         /* Stop all processing if we are to skip the remaining sprites */
08793         if (_cur.skip_sprites == -1) break;
08794 
08795         continue;
08796       } else {
08797         FioSkipBytes(num);
08798       }
08799     } else {
08800       if (_cur.skip_sprites == 0) {
08801         grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08802         DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08803         break;
08804       }
08805 
08806       if (_cur.grf_container_ver >= 2 && type == 0xFD) {
08807         /* Reference to data section. Container version >= 2 only. */
08808         FioSkipBytes(num);
08809       } else {
08810         FioSkipBytes(7);
08811         SkipSpriteData(type, num - 8);
08812       }
08813     }
08814 
08815     if (_cur.skip_sprites > 0) _cur.skip_sprites--;
08816   }
08817 }
08818 
08826 static void ActivateOldShore()
08827 {
08828   /* Use default graphics, if no shore sprites were loaded.
08829    * Should not happen, as the base set's extra grf should include some. */
08830   if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08831 
08832   if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08833     DupSprite(SPR_ORIGINALSHORE_START +  1, SPR_SHORE_BASE +  1); // SLOPE_W
08834     DupSprite(SPR_ORIGINALSHORE_START +  2, SPR_SHORE_BASE +  2); // SLOPE_S
08835     DupSprite(SPR_ORIGINALSHORE_START +  6, SPR_SHORE_BASE +  3); // SLOPE_SW
08836     DupSprite(SPR_ORIGINALSHORE_START +  0, SPR_SHORE_BASE +  4); // SLOPE_E
08837     DupSprite(SPR_ORIGINALSHORE_START +  4, SPR_SHORE_BASE +  6); // SLOPE_SE
08838     DupSprite(SPR_ORIGINALSHORE_START +  3, SPR_SHORE_BASE +  8); // SLOPE_N
08839     DupSprite(SPR_ORIGINALSHORE_START +  7, SPR_SHORE_BASE +  9); // SLOPE_NW
08840     DupSprite(SPR_ORIGINALSHORE_START +  5, SPR_SHORE_BASE + 12); // SLOPE_NE
08841   }
08842 
08843   if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08844     DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE +  0); // SLOPE_STEEP_S
08845     DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE +  5); // SLOPE_STEEP_W
08846     DupSprite(SPR_FLAT_GRASS_TILE +  7, SPR_SHORE_BASE +  7); // SLOPE_WSE
08847     DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
08848     DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
08849     DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
08850     DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
08851     DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
08852 
08853     /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
08854      *       If they would be used somewhen, then these grass tiles will most like not look as needed */
08855     DupSprite(SPR_FLAT_GRASS_TILE +  5, SPR_SHORE_BASE + 16); // SLOPE_EW
08856     DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
08857   }
08858 }
08859 
08863 static void FinalisePriceBaseMultipliers()
08864 {
08865   extern const PriceBaseSpec _price_base_specs[];
08867   static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08868 
08869   /* Evaluate grf overrides */
08870   int num_grfs = _grf_files.Length();
08871   int *grf_overrides = AllocaM(int, num_grfs);
08872   for (int i = 0; i < num_grfs; i++) {
08873     grf_overrides[i] = -1;
08874 
08875     GRFFile *source = _grf_files[i];
08876     uint32 override = _grf_id_overrides[source->grfid];
08877     if (override == 0) continue;
08878 
08879     GRFFile *dest = GetFileByGRFID(override);
08880     if (dest == NULL) continue;
08881 
08882     grf_overrides[i] = _grf_files.FindIndex(dest);
08883     assert(grf_overrides[i] >= 0);
08884   }
08885 
08886   /* Override features and price base multipliers of earlier loaded grfs */
08887   for (int i = 0; i < num_grfs; i++) {
08888     if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08889     GRFFile *source = _grf_files[i];
08890     GRFFile *dest = _grf_files[grf_overrides[i]];
08891 
08892     uint32 features = (source->grf_features | dest->grf_features) & override_features;
08893     source->grf_features |= features;
08894     dest->grf_features |= features;
08895 
08896     for (Price p = PR_BEGIN; p < PR_END; p++) {
08897       /* No price defined -> nothing to do */
08898       if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08899       DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08900       dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08901     }
08902   }
08903 
08904   /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
08905   for (int i = num_grfs - 1; i >= 0; i--) {
08906     if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08907     GRFFile *source = _grf_files[i];
08908     GRFFile *dest = _grf_files[grf_overrides[i]];
08909 
08910     uint32 features = (source->grf_features | dest->grf_features) & override_features;
08911     source->grf_features |= features;
08912     dest->grf_features |= features;
08913 
08914     for (Price p = PR_BEGIN; p < PR_END; p++) {
08915       /* Already a price defined -> nothing to do */
08916       if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08917       DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08918       dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08919     }
08920   }
08921 
08922   /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
08923   for (int i = 0; i < num_grfs; i++) {
08924     if (grf_overrides[i] < 0) continue;
08925     GRFFile *source = _grf_files[i];
08926     GRFFile *dest = _grf_files[grf_overrides[i]];
08927 
08928     uint32 features = (source->grf_features | dest->grf_features) & override_features;
08929     source->grf_features |= features;
08930     dest->grf_features |= features;
08931 
08932     for (Price p = PR_BEGIN; p < PR_END; p++) {
08933       if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08934       if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08935         DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08936       }
08937       source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08938     }
08939   }
08940 
08941   /* Apply fallback prices for grf version < 8 */
08942   const GRFFile * const *end = _grf_files.End();
08943   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08944     if ((*file)->grf_version >= 8) continue;
08945     PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08946     for (Price p = PR_BEGIN; p < PR_END; p++) {
08947       Price fallback_price = _price_base_specs[p].fallback_price;
08948       if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08949         /* No price multiplier has been set.
08950          * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
08951         price_base_multipliers[p] = price_base_multipliers[fallback_price];
08952       }
08953     }
08954   }
08955 
08956   /* Decide local/global scope of price base multipliers */
08957   for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08958     PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08959     for (Price p = PR_BEGIN; p < PR_END; p++) {
08960       if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08961         /* No multiplier was set; set it to a neutral value */
08962         price_base_multipliers[p] = 0;
08963       } else {
08964         if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08965           /* The grf does not define any objects of the feature,
08966            * so it must be a difficulty setting. Apply it globally */
08967           DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08968           SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08969           price_base_multipliers[p] = 0;
08970         } else {
08971           DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08972         }
08973       }
08974     }
08975   }
08976 }
08977 
08978 void InitDepotWindowBlockSizes();
08979 
08980 extern void InitGRFTownGeneratorNames();
08981 
08983 static void AfterLoadGRFs()
08984 {
08985   for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08986     *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08987   }
08988   _string_to_grf_mapping.clear();
08989 
08990   /* Free the action 6 override sprites. */
08991   for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08992     free((*it).second);
08993   }
08994   _grf_line_to_action6_sprite_override.clear();
08995 
08996   /* Polish cargoes */
08997   FinaliseCargoArray();
08998 
08999   /* Pre-calculate all refit masks after loading GRF files. */
09000   CalculateRefitMasks();
09001 
09002   /* Polish engines */
09003   FinaliseEngineArray();
09004 
09005   /* Set the actually used Canal properties */
09006   FinaliseCanals();
09007 
09008   /* Set the block size in the depot windows based on vehicle sprite sizes */
09009   InitDepotWindowBlockSizes();
09010 
09011   /* Add all new houses to the house array. */
09012   FinaliseHouseArray();
09013 
09014   /* Add all new industries to the industry array. */
09015   FinaliseIndustriesArray();
09016 
09017   /* Add all new objects to the object array. */
09018   FinaliseObjectsArray();
09019 
09020   InitializeSortedCargoSpecs();
09021 
09022   /* Sort the list of industry types. */
09023   SortIndustryTypes();
09024 
09025   /* Create dynamic list of industry legends for smallmap_gui.cpp */
09026   BuildIndustriesLegend();
09027 
09028   /* Add all new airports to the airports array. */
09029   FinaliseAirportsArray();
09030   BindAirportSpecs();
09031 
09032   /* Update the townname generators list */
09033   InitGRFTownGeneratorNames();
09034 
09035   /* Run all queued vehicle list order changes */
09036   CommitVehicleListOrderChanges();
09037 
09038   /* Load old shore sprites in new position, if they were replaced by ActionA */
09039   ActivateOldShore();
09040 
09041   /* Set up custom rail types */
09042   InitRailTypes();
09043 
09044   Engine *e;
09045   FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
09046     if (_gted[e->index].rv_max_speed != 0) {
09047       /* Set RV maximum speed from the mph/0.8 unit value */
09048       e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
09049     }
09050   }
09051 
09052   FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
09053     RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
09054     if (railtype == INVALID_RAILTYPE) {
09055       /* Rail type is not available, so disable this engine */
09056       e->info.climates = 0;
09057     } else {
09058       e->u.rail.railtype = railtype;
09059     }
09060   }
09061 
09062   SetYearEngineAgingStops();
09063 
09064   FinalisePriceBaseMultipliers();
09065 
09066   /* Deallocate temporary loading data */
09067   free(_gted);
09068   _grm_sprites.clear();
09069 }
09070 
09076 void LoadNewGRF(uint load_index, uint file_index)
09077 {
09078   /* In case of networking we need to "sync" the start values
09079    * so all NewGRFs are loaded equally. For this we use the
09080    * start date of the game and we set the counters, etc. to
09081    * 0 so they're the same too. */
09082   Date date            = _date;
09083   Year year            = _cur_year;
09084   DateFract date_fract = _date_fract;
09085   uint16 tick_counter  = _tick_counter;
09086   byte display_opt     = _display_opt;
09087 
09088   if (_networking) {
09089     _cur_year     = _settings_game.game_creation.starting_year;
09090     _date         = ConvertYMDToDate(_cur_year, 0, 1);
09091     _date_fract   = 0;
09092     _tick_counter = 0;
09093     _display_opt  = 0;
09094   }
09095 
09096   InitializeGRFSpecial();
09097 
09098   ResetNewGRFData();
09099 
09100   /*
09101    * Reset the status of all files, so we can 'retry' to load them.
09102    * This is needed when one for example rearranges the NewGRFs in-game
09103    * and a previously disabled NewGRF becomes useable. If it would not
09104    * be reset, the NewGRF would remain disabled even though it should
09105    * have been enabled.
09106    */
09107   for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09108     if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
09109   }
09110 
09111   _cur.spriteid = load_index;
09112 
09113   /* Load newgrf sprites
09114    * in each loading stage, (try to) open each file specified in the config
09115    * and load information from it. */
09116   for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
09117     /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
09118      * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
09119     for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09120       if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
09121     }
09122 
09123     if (stage == GLS_RESERVE) {
09124       static const uint32 overrides[][2] = {
09125         { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
09126         { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
09127         { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
09128       };
09129       for (size_t i = 0; i < lengthof(overrides); i++) {
09130         SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
09131       }
09132     }
09133 
09134     uint slot = file_index;
09135 
09136     _cur.stage = stage;
09137     for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09138       if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
09139       if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
09140 
09141       Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
09142       if (!FioCheckFileExists(c->filename, subdir)) {
09143         DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
09144         c->status = GCS_NOT_FOUND;
09145         continue;
09146       }
09147 
09148       if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
09149       LoadNewGRFFile(c, slot++, stage, subdir);
09150       if (stage == GLS_RESERVE) {
09151         SetBit(c->flags, GCF_RESERVED);
09152       } else if (stage == GLS_ACTIVATION) {
09153         ClrBit(c->flags, GCF_RESERVED);
09154         assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
09155         ClearTemporaryNewGRFData(_cur.grffile);
09156         BuildCargoTranslationMap();
09157         DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
09158       } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
09159         /* We're not going to activate this, so free whatever data we allocated */
09160         ClearTemporaryNewGRFData(_cur.grffile);
09161       }
09162     }
09163   }
09164 
09165   /* Pseudo sprite processing is finished; free temporary stuff */
09166   _cur.ClearDataForNextFile();
09167 
09168   /* Call any functions that should be run after GRFs have been loaded. */
09169   AfterLoadGRFs();
09170 
09171   /* Now revert back to the original situation */
09172   _cur_year     = year;
09173   _date         = date;
09174   _date_fract   = date_fract;
09175   _tick_counter = tick_counter;
09176   _display_opt  = display_opt;
09177 }