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