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