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