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