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 && HasBit(_cargo_mask, ctype)) {
01045
01046 ei->cargo_type = ctype;
01047 } else {
01048 ei->cargo_type = CT_INVALID;
01049 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
01050 }
01051 break;
01052 }
01053
01054 case PROP_TRAIN_WEIGHT:
01055 SB(rvi->weight, 0, 8, buf->ReadByte());
01056 break;
01057
01058 case PROP_TRAIN_COST_FACTOR:
01059 rvi->cost_factor = buf->ReadByte();
01060 break;
01061
01062 case 0x18:
01063 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
01064 buf->ReadByte();
01065 break;
01066
01067 case 0x19: {
01068
01069
01070
01071
01072
01073
01074
01075 uint8 traction = buf->ReadByte();
01076 EngineClass engclass;
01077
01078 if (traction <= 0x07) {
01079 engclass = EC_STEAM;
01080 } else if (traction <= 0x27) {
01081 engclass = EC_DIESEL;
01082 } else if (traction <= 0x31) {
01083 engclass = EC_ELECTRIC;
01084 } else if (traction <= 0x37) {
01085 engclass = EC_MONORAIL;
01086 } else if (traction <= 0x41) {
01087 engclass = EC_MAGLEV;
01088 } else {
01089 break;
01090 }
01091
01092 if (_cur.grffile->railtype_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 && HasBit(_cargo_mask, ctype)) {
01280
01281 ei->cargo_type = ctype;
01282 } else {
01283 ei->cargo_type = CT_INVALID;
01284 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
01285 }
01286 break;
01287 }
01288
01289 case PROP_ROADVEH_COST_FACTOR:
01290 rvi->cost_factor = buf->ReadByte();
01291 break;
01292
01293 case 0x12:
01294 rvi->sfx = buf->ReadByte();
01295 break;
01296
01297 case PROP_ROADVEH_POWER:
01298 rvi->power = buf->ReadByte();
01299 break;
01300
01301 case PROP_ROADVEH_WEIGHT:
01302 rvi->weight = buf->ReadByte();
01303 break;
01304
01305 case PROP_ROADVEH_SPEED:
01306 _gted[e->index].rv_max_speed = buf->ReadByte();
01307 break;
01308
01309 case 0x16: {
01310 uint32 mask = buf->ReadDWord();
01311 _gted[e->index].UpdateRefittability(mask != 0);
01312 ei->refit_mask = TranslateRefitMask(mask);
01313 _gted[e->index].defaultcargo_grf = _cur.grffile;
01314 break;
01315 }
01316
01317 case 0x17:
01318 ei->callback_mask = buf->ReadByte();
01319 break;
01320
01321 case PROP_ROADVEH_TRACTIVE_EFFORT:
01322 rvi->tractive_effort = buf->ReadByte();
01323 break;
01324
01325 case 0x19:
01326 rvi->air_drag = buf->ReadByte();
01327 break;
01328
01329 case 0x1A:
01330 ei->refit_cost = buf->ReadByte();
01331 break;
01332
01333 case 0x1B:
01334 ei->retire_early = buf->ReadByte();
01335 break;
01336
01337 case 0x1C:
01338 ei->misc_flags = buf->ReadByte();
01339 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01340 break;
01341
01342 case 0x1D:
01343 _gted[e->index].cargo_allowed = buf->ReadWord();
01344 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
01345 _gted[e->index].defaultcargo_grf = _cur.grffile;
01346 break;
01347
01348 case 0x1E:
01349 _gted[e->index].cargo_disallowed = buf->ReadWord();
01350 _gted[e->index].UpdateRefittability(false);
01351 break;
01352
01353 case 0x1F:
01354 ei->base_intro = buf->ReadDWord();
01355 break;
01356
01357 case 0x20:
01358 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01359 break;
01360
01361 case 0x21:
01362 rvi->visual_effect = buf->ReadByte();
01363
01364
01365 if (rvi->visual_effect == VE_DEFAULT) {
01366 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
01367 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
01368 }
01369 break;
01370
01371 case PROP_ROADVEH_CARGO_AGE_PERIOD:
01372 ei->cargo_age_period = buf->ReadWord();
01373 break;
01374
01375 case PROP_ROADVEH_SHORTEN_FACTOR:
01376 rvi->shorten_factor = buf->ReadByte();
01377 break;
01378
01379 case 0x24:
01380 case 0x25: {
01381 uint8 count = buf->ReadByte();
01382 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
01383 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
01384 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
01385 ctt = 0;
01386 while (count--) {
01387 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
01388 if (ctype == CT_INVALID) continue;
01389 SetBit(ctt, ctype);
01390 }
01391 break;
01392 }
01393
01394 default:
01395 ret = CommonVehicleChangeInfo(ei, prop, buf);
01396 break;
01397 }
01398 }
01399
01400 return ret;
01401 }
01402
01411 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
01412 {
01413 ChangeInfoResult ret = CIR_SUCCESS;
01414
01415 for (int i = 0; i < numinfo; i++) {
01416 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
01417 if (e == NULL) return CIR_INVALID_ID;
01418
01419 EngineInfo *ei = &e->info;
01420 ShipVehicleInfo *svi = &e->u.ship;
01421
01422 switch (prop) {
01423 case 0x08: {
01424 uint8 spriteid = buf->ReadByte();
01425
01426
01427 if (spriteid == 0xFF) spriteid = 0xFD;
01428
01429 if (spriteid < 0xFD) spriteid >>= 1;
01430
01431 svi->image_index = spriteid;
01432 break;
01433 }
01434
01435 case 0x09:
01436 svi->old_refittable = (buf->ReadByte() != 0);
01437 break;
01438
01439 case PROP_SHIP_COST_FACTOR:
01440 svi->cost_factor = buf->ReadByte();
01441 break;
01442
01443 case PROP_SHIP_SPEED:
01444 svi->max_speed = buf->ReadByte();
01445 break;
01446
01447 case 0x0C: {
01448 _gted[e->index].defaultcargo_grf = _cur.grffile;
01449 uint8 ctype = buf->ReadByte();
01450
01451 if (ctype == 0xFF) {
01452
01453 ei->cargo_type = CT_INVALID;
01454 } else if (_cur.grffile->grf_version >= 8) {
01455
01456 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
01457 } else if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
01458
01459 ei->cargo_type = ctype;
01460 } else {
01461 ei->cargo_type = CT_INVALID;
01462 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
01463 }
01464 break;
01465 }
01466
01467 case PROP_SHIP_CARGO_CAPACITY:
01468 svi->capacity = buf->ReadWord();
01469 break;
01470
01471 case PROP_SHIP_RUNNING_COST_FACTOR:
01472 svi->running_cost = buf->ReadByte();
01473 break;
01474
01475 case 0x10:
01476 svi->sfx = buf->ReadByte();
01477 break;
01478
01479 case 0x11: {
01480 uint32 mask = buf->ReadDWord();
01481 _gted[e->index].UpdateRefittability(mask != 0);
01482 ei->refit_mask = TranslateRefitMask(mask);
01483 _gted[e->index].defaultcargo_grf = _cur.grffile;
01484 break;
01485 }
01486
01487 case 0x12:
01488 ei->callback_mask = buf->ReadByte();
01489 break;
01490
01491 case 0x13:
01492 ei->refit_cost = buf->ReadByte();
01493 break;
01494
01495 case 0x14:
01496 svi->ocean_speed_frac = buf->ReadByte();
01497 break;
01498
01499 case 0x15:
01500 svi->canal_speed_frac = buf->ReadByte();
01501 break;
01502
01503 case 0x16:
01504 ei->retire_early = buf->ReadByte();
01505 break;
01506
01507 case 0x17:
01508 ei->misc_flags = buf->ReadByte();
01509 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01510 break;
01511
01512 case 0x18:
01513 _gted[e->index].cargo_allowed = buf->ReadWord();
01514 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
01515 _gted[e->index].defaultcargo_grf = _cur.grffile;
01516 break;
01517
01518 case 0x19:
01519 _gted[e->index].cargo_disallowed = buf->ReadWord();
01520 _gted[e->index].UpdateRefittability(false);
01521 break;
01522
01523 case 0x1A:
01524 ei->base_intro = buf->ReadDWord();
01525 break;
01526
01527 case 0x1B:
01528 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01529 break;
01530
01531 case 0x1C:
01532 svi->visual_effect = buf->ReadByte();
01533
01534
01535 if (svi->visual_effect == VE_DEFAULT) {
01536 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
01537 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
01538 }
01539 break;
01540
01541 case PROP_SHIP_CARGO_AGE_PERIOD:
01542 ei->cargo_age_period = buf->ReadWord();
01543 break;
01544
01545 case 0x1E:
01546 case 0x1F: {
01547 uint8 count = buf->ReadByte();
01548 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
01549 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
01550 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
01551 ctt = 0;
01552 while (count--) {
01553 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
01554 if (ctype == CT_INVALID) continue;
01555 SetBit(ctt, ctype);
01556 }
01557 break;
01558 }
01559
01560 default:
01561 ret = CommonVehicleChangeInfo(ei, prop, buf);
01562 break;
01563 }
01564 }
01565
01566 return ret;
01567 }
01568
01577 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
01578 {
01579 ChangeInfoResult ret = CIR_SUCCESS;
01580
01581 for (int i = 0; i < numinfo; i++) {
01582 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
01583 if (e == NULL) return CIR_INVALID_ID;
01584
01585 EngineInfo *ei = &e->info;
01586 AircraftVehicleInfo *avi = &e->u.air;
01587
01588 switch (prop) {
01589 case 0x08: {
01590 uint8 spriteid = buf->ReadByte();
01591
01592
01593 if (spriteid == 0xFF) spriteid = 0xFD;
01594
01595 if (spriteid < 0xFD) spriteid >>= 1;
01596
01597 avi->image_index = spriteid;
01598 break;
01599 }
01600
01601 case 0x09:
01602 if (buf->ReadByte() == 0) {
01603 avi->subtype = AIR_HELI;
01604 } else {
01605 SB(avi->subtype, 0, 1, 1);
01606 }
01607 break;
01608
01609 case 0x0A:
01610 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
01611 break;
01612
01613 case PROP_AIRCRAFT_COST_FACTOR:
01614 avi->cost_factor = buf->ReadByte();
01615 break;
01616
01617 case PROP_AIRCRAFT_SPEED:
01618 avi->max_speed = (buf->ReadByte() * 128) / 10;
01619 break;
01620
01621 case 0x0D:
01622 avi->acceleration = (buf->ReadByte() * 128) / 10;
01623 break;
01624
01625 case PROP_AIRCRAFT_RUNNING_COST_FACTOR:
01626 avi->running_cost = buf->ReadByte();
01627 break;
01628
01629 case PROP_AIRCRAFT_PASSENGER_CAPACITY:
01630 avi->passenger_capacity = buf->ReadWord();
01631 break;
01632
01633 case PROP_AIRCRAFT_MAIL_CAPACITY:
01634 avi->mail_capacity = buf->ReadByte();
01635 break;
01636
01637 case 0x12:
01638 avi->sfx = buf->ReadByte();
01639 break;
01640
01641 case 0x13: {
01642 uint32 mask = buf->ReadDWord();
01643 _gted[e->index].UpdateRefittability(mask != 0);
01644 ei->refit_mask = TranslateRefitMask(mask);
01645 _gted[e->index].defaultcargo_grf = _cur.grffile;
01646 break;
01647 }
01648
01649 case 0x14:
01650 ei->callback_mask = buf->ReadByte();
01651 break;
01652
01653 case 0x15:
01654 ei->refit_cost = buf->ReadByte();
01655 break;
01656
01657 case 0x16:
01658 ei->retire_early = buf->ReadByte();
01659 break;
01660
01661 case 0x17:
01662 ei->misc_flags = buf->ReadByte();
01663 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01664 break;
01665
01666 case 0x18:
01667 _gted[e->index].cargo_allowed = buf->ReadWord();
01668 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
01669 _gted[e->index].defaultcargo_grf = _cur.grffile;
01670 break;
01671
01672 case 0x19:
01673 _gted[e->index].cargo_disallowed = buf->ReadWord();
01674 _gted[e->index].UpdateRefittability(false);
01675 break;
01676
01677 case 0x1A:
01678 ei->base_intro = buf->ReadDWord();
01679 break;
01680
01681 case 0x1B:
01682 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
01683 break;
01684
01685 case PROP_AIRCRAFT_CARGO_AGE_PERIOD:
01686 ei->cargo_age_period = buf->ReadWord();
01687 break;
01688
01689 case 0x1D:
01690 case 0x1E: {
01691 uint8 count = buf->ReadByte();
01692 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
01693 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
01694 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
01695 ctt = 0;
01696 while (count--) {
01697 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
01698 if (ctype == CT_INVALID) continue;
01699 SetBit(ctt, ctype);
01700 }
01701 break;
01702 }
01703
01704 case PROP_AIRCRAFT_RANGE:
01705 avi->max_range = buf->ReadWord();
01706 break;
01707
01708 default:
01709 ret = CommonVehicleChangeInfo(ei, prop, buf);
01710 break;
01711 }
01712 }
01713
01714 return ret;
01715 }
01716
01725 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
01726 {
01727 ChangeInfoResult ret = CIR_SUCCESS;
01728
01729 if (stid + numinfo > MAX_STATIONS) {
01730 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
01731 return CIR_INVALID_ID;
01732 }
01733
01734
01735 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
01736
01737 for (int i = 0; i < numinfo; i++) {
01738 StationSpec *statspec = _cur.grffile->stations[stid + i];
01739
01740
01741 if (statspec == NULL && prop != 0x08) {
01742 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
01743 return CIR_INVALID_ID;
01744 }
01745
01746 switch (prop) {
01747 case 0x08: {
01748 StationSpec **spec = &_cur.grffile->stations[stid + i];
01749
01750
01751 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
01752
01753
01754 uint32 classid = buf->ReadDWord();
01755 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
01756 break;
01757 }
01758
01759 case 0x09:
01760 statspec->tiles = buf->ReadExtendedByte();
01761 delete[] statspec->renderdata;
01762 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01763
01764 for (uint t = 0; t < statspec->tiles; t++) {
01765 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
01766 dts->consistent_max_offset = UINT16_MAX;
01767
01768 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
01769 buf->Skip(4);
01770 extern const DrawTileSprites _station_display_datas_rail[8];
01771 dts->Clone(&_station_display_datas_rail[t % 8]);
01772 continue;
01773 }
01774
01775 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
01776
01777 if (_cur.skip_sprites < 0) return CIR_DISABLED;
01778
01779 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
01780 tmp_layout.Clear();
01781 for (;;) {
01782
01783 DrawTileSeqStruct *dtss = tmp_layout.Append();
01784 MemSetT(dtss, 0);
01785
01786 dtss->delta_x = buf->ReadByte();
01787 if (dtss->IsTerminator()) break;
01788 dtss->delta_y = buf->ReadByte();
01789 dtss->delta_z = buf->ReadByte();
01790 dtss->size_x = buf->ReadByte();
01791 dtss->size_y = buf->ReadByte();
01792 dtss->size_z = buf->ReadByte();
01793
01794 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
01795
01796 if (_cur.skip_sprites < 0) return CIR_DISABLED;
01797 }
01798 dts->Clone(tmp_layout.Begin());
01799 }
01800 break;
01801
01802 case 0x0A: {
01803 byte srcid = buf->ReadByte();
01804 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
01805
01806 if (srcstatspec == NULL) {
01807 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
01808 continue;
01809 }
01810
01811 delete[] statspec->renderdata;
01812
01813 statspec->tiles = srcstatspec->tiles;
01814 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01815 for (uint t = 0; t < statspec->tiles; t++) {
01816 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
01817 }
01818 break;
01819 }
01820
01821 case 0x0B:
01822 statspec->callback_mask = buf->ReadByte();
01823 break;
01824
01825 case 0x0C:
01826 statspec->disallowed_platforms = buf->ReadByte();
01827 break;
01828
01829 case 0x0D:
01830 statspec->disallowed_lengths = buf->ReadByte();
01831 break;
01832
01833 case 0x0E:
01834 statspec->copied_layouts = false;
01835
01836 while (buf->HasData()) {
01837 byte length = buf->ReadByte();
01838 byte number = buf->ReadByte();
01839 StationLayout layout;
01840 uint l, p;
01841
01842 if (length == 0 || number == 0) break;
01843
01844 if (length > statspec->lengths) {
01845 statspec->platforms = ReallocT(statspec->platforms, length);
01846 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
01847
01848 statspec->layouts = ReallocT(statspec->layouts, length);
01849 memset(statspec->layouts + statspec->lengths, 0,
01850 (length - statspec->lengths) * sizeof(*statspec->layouts));
01851
01852 statspec->lengths = length;
01853 }
01854 l = length - 1;
01855
01856 if (number > statspec->platforms[l]) {
01857 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
01858
01859 memset(statspec->layouts[l] + statspec->platforms[l], 0,
01860 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
01861
01862 statspec->platforms[l] = number;
01863 }
01864
01865 p = 0;
01866 layout = MallocT<byte>(length * number);
01867 try {
01868 for (l = 0; l < length; l++) {
01869 for (p = 0; p < number; p++) {
01870 layout[l * number + p] = buf->ReadByte();
01871 }
01872 }
01873 } catch (...) {
01874 free(layout);
01875 throw;
01876 }
01877
01878 l--;
01879 p--;
01880 free(statspec->layouts[l][p]);
01881 statspec->layouts[l][p] = layout;
01882 }
01883 break;
01884
01885 case 0x0F: {
01886 byte srcid = buf->ReadByte();
01887 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
01888
01889 if (srcstatspec == NULL) {
01890 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
01891 continue;
01892 }
01893
01894 statspec->lengths = srcstatspec->lengths;
01895 statspec->platforms = srcstatspec->platforms;
01896 statspec->layouts = srcstatspec->layouts;
01897 statspec->copied_layouts = true;
01898 break;
01899 }
01900
01901 case 0x10:
01902 statspec->cargo_threshold = buf->ReadWord();
01903 break;
01904
01905 case 0x11:
01906 statspec->pylons = buf->ReadByte();
01907 break;
01908
01909 case 0x12:
01910 statspec->cargo_triggers = buf->ReadDWord();
01911 break;
01912
01913 case 0x13:
01914 statspec->flags = buf->ReadByte();
01915 break;
01916
01917 case 0x14:
01918 statspec->wires = buf->ReadByte();
01919 break;
01920
01921 case 0x15:
01922 statspec->blocked = buf->ReadByte();
01923 break;
01924
01925 case 0x16:
01926 statspec->animation.frames = buf->ReadByte();
01927 statspec->animation.status = buf->ReadByte();
01928 break;
01929
01930 case 0x17:
01931 statspec->animation.speed = buf->ReadByte();
01932 break;
01933
01934 case 0x18:
01935 statspec->animation.triggers = buf->ReadWord();
01936 break;
01937
01938 case 0x1A:
01939 statspec->tiles = buf->ReadExtendedByte();
01940 delete[] statspec->renderdata;
01941 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
01942
01943 for (uint t = 0; t < statspec->tiles; t++) {
01944 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
01945 uint num_building_sprites = buf->ReadByte();
01946
01947 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
01948 }
01949 break;
01950
01951 default:
01952 ret = CIR_UNKNOWN;
01953 break;
01954 }
01955 }
01956
01957 return ret;
01958 }
01959
01968 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
01969 {
01970 ChangeInfoResult ret = CIR_SUCCESS;
01971
01972 if (id + numinfo > CF_END) {
01973 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END);
01974 return CIR_INVALID_ID;
01975 }
01976
01977 for (int i = 0; i < numinfo; i++) {
01978 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
01979
01980 switch (prop) {
01981 case 0x08:
01982 cp->callback_mask = buf->ReadByte();
01983 break;
01984
01985 case 0x09:
01986 cp->flags = buf->ReadByte();
01987 break;
01988
01989 default:
01990 ret = CIR_UNKNOWN;
01991 break;
01992 }
01993 }
01994
01995 return ret;
01996 }
01997
02006 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
02007 {
02008 ChangeInfoResult ret = CIR_SUCCESS;
02009
02010 if (brid + numinfo > MAX_BRIDGES) {
02011 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
02012 return CIR_INVALID_ID;
02013 }
02014
02015 for (int i = 0; i < numinfo; i++) {
02016 BridgeSpec *bridge = &_bridge[brid + i];
02017
02018 switch (prop) {
02019 case 0x08: {
02020
02021 byte year = buf->ReadByte();
02022 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
02023 break;
02024 }
02025
02026 case 0x09:
02027 bridge->min_length = buf->ReadByte();
02028 break;
02029
02030 case 0x0A:
02031 bridge->max_length = buf->ReadByte();
02032 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
02033 break;
02034
02035 case 0x0B:
02036 bridge->price = buf->ReadByte();
02037 break;
02038
02039 case 0x0C:
02040 bridge->speed = buf->ReadWord();
02041 break;
02042
02043 case 0x0D: {
02044 byte tableid = buf->ReadByte();
02045 byte numtables = buf->ReadByte();
02046
02047 if (bridge->sprite_table == NULL) {
02048
02049 bridge->sprite_table = CallocT<PalSpriteID*>(7);
02050 }
02051
02052 for (; numtables-- != 0; tableid++) {
02053 if (tableid >= 7) {
02054 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
02055 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
02056 continue;
02057 }
02058
02059 if (bridge->sprite_table[tableid] == NULL) {
02060 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
02061 }
02062
02063 for (byte sprite = 0; sprite < 32; sprite++) {
02064 SpriteID image = buf->ReadWord();
02065 PaletteID pal = buf->ReadWord();
02066
02067 bridge->sprite_table[tableid][sprite].sprite = image;
02068 bridge->sprite_table[tableid][sprite].pal = pal;
02069
02070 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
02071 }
02072 }
02073 break;
02074 }
02075
02076 case 0x0E:
02077 bridge->flags = buf->ReadByte();
02078 break;
02079
02080 case 0x0F:
02081 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
02082 break;
02083
02084 case 0x10: {
02085 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
02086 if (newone != STR_UNDEFINED) bridge->material = newone;
02087 break;
02088 }
02089
02090 case 0x11:
02091 case 0x12: {
02092 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
02093 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
02094 break;
02095 }
02096
02097 case 0x13:
02098 bridge->price = buf->ReadWord();
02099 break;
02100
02101 default:
02102 ret = CIR_UNKNOWN;
02103 break;
02104 }
02105 }
02106
02107 return ret;
02108 }
02109
02116 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
02117 {
02118 ChangeInfoResult ret = CIR_SUCCESS;
02119
02120 switch (prop) {
02121 case 0x09:
02122 case 0x0B:
02123 case 0x0C:
02124 case 0x0D:
02125 case 0x0E:
02126 case 0x0F:
02127 case 0x11:
02128 case 0x14:
02129 case 0x15:
02130 case 0x16:
02131 case 0x18:
02132 case 0x19:
02133 case 0x1A:
02134 case 0x1B:
02135 case 0x1C:
02136 case 0x1D:
02137 case 0x1F:
02138 buf->ReadByte();
02139 break;
02140
02141 case 0x0A:
02142 case 0x10:
02143 case 0x12:
02144 case 0x13:
02145 case 0x21:
02146 case 0x22:
02147 buf->ReadWord();
02148 break;
02149
02150 case 0x1E:
02151 buf->ReadDWord();
02152 break;
02153
02154 case 0x17:
02155 for (uint j = 0; j < 4; j++) buf->ReadByte();
02156 break;
02157
02158 case 0x20: {
02159 byte count = buf->ReadByte();
02160 for (byte j = 0; j < count; j++) buf->ReadByte();
02161 break;
02162 }
02163
02164 default:
02165 ret = CIR_UNKNOWN;
02166 break;
02167 }
02168 return ret;
02169 }
02170
02179 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
02180 {
02181 ChangeInfoResult ret = CIR_SUCCESS;
02182
02183 if (hid + numinfo > HOUSE_MAX) {
02184 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
02185 return CIR_INVALID_ID;
02186 }
02187
02188
02189 if (_cur.grffile->housespec == NULL) {
02190 _cur.grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
02191 }
02192
02193 for (int i = 0; i < numinfo; i++) {
02194 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
02195
02196 if (prop != 0x08 && housespec == NULL) {
02197
02198 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
02199 if (cir > ret) ret = cir;
02200 continue;
02201 }
02202
02203 switch (prop) {
02204 case 0x08: {
02205 HouseSpec **house = &_cur.grffile->housespec[hid + i];
02206 byte subs_id = buf->ReadByte();
02207
02208 if (subs_id == 0xFF) {
02209
02210
02211 HouseSpec::Get(hid + i)->enabled = false;
02212 continue;
02213 } else if (subs_id >= NEW_HOUSE_OFFSET) {
02214
02215 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
02216 continue;
02217 }
02218
02219
02220 if (*house == NULL) *house = CallocT<HouseSpec>(1);
02221
02222 housespec = *house;
02223
02224 MemCpyT(housespec, HouseSpec::Get(subs_id));
02225
02226 housespec->enabled = true;
02227 housespec->grf_prop.local_id = hid + i;
02228 housespec->grf_prop.subst_id = subs_id;
02229 housespec->grf_prop.grffile = _cur.grffile;
02230 housespec->random_colour[0] = 0x04;
02231 housespec->random_colour[1] = 0x08;
02232 housespec->random_colour[2] = 0x0C;
02233 housespec->random_colour[3] = 0x06;
02234
02235
02236
02237
02238
02239 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
02240 housespec->cargo_acceptance[2] = 0;
02241 }
02242
02243 _loaded_newgrf_features.has_newhouses = true;
02244 break;
02245 }
02246
02247 case 0x09:
02248 housespec->building_flags = (BuildingFlags)buf->ReadByte();
02249 break;
02250
02251 case 0x0A: {
02252 uint16 years = buf->ReadWord();
02253 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
02254 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
02255 break;
02256 }
02257
02258 case 0x0B:
02259 housespec->population = buf->ReadByte();
02260 break;
02261
02262 case 0x0C:
02263 housespec->mail_generation = buf->ReadByte();
02264 break;
02265
02266 case 0x0D:
02267 case 0x0E:
02268 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
02269 break;
02270
02271 case 0x0F: {
02272 int8 goods = buf->ReadByte();
02273
02274
02275
02276 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
02277 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
02278
02279
02280 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
02281
02282 housespec->accepts_cargo[2] = cid;
02283 housespec->cargo_acceptance[2] = abs(goods);
02284 break;
02285 }
02286
02287 case 0x10:
02288 housespec->remove_rating_decrease = buf->ReadWord();
02289 break;
02290
02291 case 0x11:
02292 housespec->removal_cost = buf->ReadByte();
02293 break;
02294
02295 case 0x12:
02296 housespec->building_name = buf->ReadWord();
02297 _string_to_grf_mapping[&housespec->building_name] = _cur.grffile->grfid;
02298 break;
02299
02300 case 0x13:
02301 housespec->building_availability = (HouseZones)buf->ReadWord();
02302 break;
02303
02304 case 0x14:
02305 housespec->callback_mask |= buf->ReadByte();
02306 break;
02307
02308 case 0x15: {
02309 byte override = buf->ReadByte();
02310
02311
02312 if (override >= NEW_HOUSE_OFFSET) {
02313 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
02314 continue;
02315 }
02316
02317 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
02318 break;
02319 }
02320
02321 case 0x16:
02322 housespec->processing_time = min(buf->ReadByte(), 63);
02323 break;
02324
02325 case 0x17:
02326 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
02327 break;
02328
02329 case 0x18:
02330 housespec->probability = buf->ReadByte();
02331 break;
02332
02333 case 0x19:
02334 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
02335 break;
02336
02337 case 0x1A:
02338 housespec->animation.frames = buf->ReadByte();
02339 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
02340 SB(housespec->animation.frames, 7, 1, 0);
02341 break;
02342
02343 case 0x1B:
02344 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
02345 break;
02346
02347 case 0x1C:
02348 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
02349 break;
02350
02351 case 0x1D:
02352 housespec->callback_mask |= (buf->ReadByte() << 8);
02353 break;
02354
02355 case 0x1E: {
02356 uint32 cargotypes = buf->ReadDWord();
02357
02358
02359 if (cargotypes == 0xFFFFFFFF) break;
02360
02361 for (uint j = 0; j < 3; j++) {
02362
02363 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
02364 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
02365
02366 if (cargo == CT_INVALID) {
02367
02368 housespec->cargo_acceptance[j] = 0;
02369 } else {
02370 housespec->accepts_cargo[j] = cargo;
02371 }
02372 }
02373 break;
02374 }
02375
02376 case 0x1F:
02377 housespec->minimum_life = buf->ReadByte();
02378 break;
02379
02380 case 0x20: {
02381 byte count = buf->ReadByte();
02382 for (byte j = 0; j < count; j++) {
02383 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
02384 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
02385 }
02386 break;
02387 }
02388
02389 case 0x21:
02390 housespec->min_year = buf->ReadWord();
02391 break;
02392
02393 case 0x22:
02394 housespec->max_year = buf->ReadWord();
02395 break;
02396
02397 default:
02398 ret = CIR_UNKNOWN;
02399 break;
02400 }
02401 }
02402
02403 return ret;
02404 }
02405
02412 const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
02413 {
02414
02415 const GRFFile *grffile = GetFileByGRFID(grfid);
02416 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
02417 }
02418
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 uint8 feature = buf->ReadByte();
04383 uint8 num_sets = buf->ReadByte();
04384 uint16 first_set = 0;
04385
04386 if (num_sets == 0 && buf->HasData(2)) {
04387
04388
04389 first_set = buf->ReadExtendedByte();
04390 num_sets = buf->ReadExtendedByte();
04391 }
04392 uint16 num_ents = buf->ReadExtendedByte();
04393
04394 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
04395
04396 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
04397 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
04398 );
04399
04400 for (int i = 0; i < num_sets * num_ents; i++) {
04401 _cur.nfo_line++;
04402 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
04403 }
04404 }
04405
04406
04407 static void SkipAct1(ByteReader *buf)
04408 {
04409 buf->ReadByte();
04410 uint8 num_sets = buf->ReadByte();
04411 uint16 num_ents = buf->ReadExtendedByte();
04412
04413 _cur.skip_sprites = num_sets * num_ents;
04414
04415 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
04416 }
04417
04418
04419
04420 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
04421 {
04422 if (HasBit(groupid, 15)) {
04423 assert(CallbackResultSpriteGroup::CanAllocateItem());
04424 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
04425 }
04426
04427 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04428 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
04429 return NULL;
04430 }
04431
04432 return _cur.spritegroups[groupid];
04433 }
04434
04443 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
04444 {
04445 if (HasBit(spriteid, 15)) {
04446 assert(CallbackResultSpriteGroup::CanAllocateItem());
04447 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
04448 }
04449
04450 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
04451 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
04452 return NULL;
04453 }
04454
04455 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
04456 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
04457
04458
04459 assert(spriteset_start + num_sprites <= _cur.spriteid);
04460
04461 assert(ResultSpriteGroup::CanAllocateItem());
04462 return new ResultSpriteGroup(spriteset_start, num_sprites);
04463 }
04464
04465
04466 static void NewSpriteGroup(ByteReader *buf)
04467 {
04468
04469
04470
04471
04472
04473
04474
04475
04476
04477
04478 SpriteGroup *act_group = NULL;
04479
04480 uint8 feature = buf->ReadByte();
04481 uint8 setid = buf->ReadByte();
04482 uint8 type = buf->ReadByte();
04483
04484
04485
04486
04487
04488 switch (type) {
04489
04490 case 0x81:
04491 case 0x82:
04492 case 0x85:
04493 case 0x86:
04494 case 0x89:
04495 case 0x8A:
04496 {
04497 byte varadjust;
04498 byte varsize;
04499
04500 assert(DeterministicSpriteGroup::CanAllocateItem());
04501 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
04502 act_group = group;
04503 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04504
04505 switch (GB(type, 2, 2)) {
04506 default: NOT_REACHED();
04507 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
04508 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
04509 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
04510 }
04511
04512 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
04513 adjusts.Clear();
04514
04515
04516
04517 do {
04518 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
04519
04520
04521 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
04522 adjust->variable = buf->ReadByte();
04523 if (adjust->variable == 0x7E) {
04524
04525 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
04526 } else {
04527 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
04528 }
04529
04530 varadjust = buf->ReadByte();
04531 adjust->shift_num = GB(varadjust, 0, 5);
04532 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
04533 adjust->and_mask = buf->ReadVarSize(varsize);
04534
04535 if (adjust->type != DSGA_TYPE_NONE) {
04536 adjust->add_val = buf->ReadVarSize(varsize);
04537 adjust->divmod_val = buf->ReadVarSize(varsize);
04538 } else {
04539 adjust->add_val = 0;
04540 adjust->divmod_val = 0;
04541 }
04542
04543
04544 } while (HasBit(varadjust, 5));
04545
04546 group->num_adjusts = adjusts.Length();
04547 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
04548 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
04549
04550 group->num_ranges = buf->ReadByte();
04551 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
04552
04553 for (uint i = 0; i < group->num_ranges; i++) {
04554 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04555 group->ranges[i].low = buf->ReadVarSize(varsize);
04556 group->ranges[i].high = buf->ReadVarSize(varsize);
04557 }
04558
04559 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04560 break;
04561 }
04562
04563
04564 case 0x80:
04565 case 0x83:
04566 case 0x84:
04567 {
04568 assert(RandomizedSpriteGroup::CanAllocateItem());
04569 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
04570 act_group = group;
04571 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04572
04573 if (HasBit(type, 2)) {
04574 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
04575 group->count = buf->ReadByte();
04576 }
04577
04578 uint8 triggers = buf->ReadByte();
04579 group->triggers = GB(triggers, 0, 7);
04580 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
04581 group->lowest_randbit = buf->ReadByte();
04582 group->num_groups = buf->ReadByte();
04583 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
04584
04585 for (uint i = 0; i < group->num_groups; i++) {
04586 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
04587 }
04588
04589 break;
04590 }
04591
04592
04593 default:
04594 {
04595 switch (feature) {
04596 case GSF_TRAINS:
04597 case GSF_ROADVEHICLES:
04598 case GSF_SHIPS:
04599 case GSF_AIRCRAFT:
04600 case GSF_STATIONS:
04601 case GSF_CANALS:
04602 case GSF_CARGOES:
04603 case GSF_AIRPORTS:
04604 case GSF_RAILTYPES:
04605 {
04606 byte num_loaded = type;
04607 byte num_loading = buf->ReadByte();
04608
04609 if (!_cur.HasValidSpriteSets(feature)) {
04610 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
04611 return;
04612 }
04613
04614 assert(RealSpriteGroup::CanAllocateItem());
04615 RealSpriteGroup *group = new RealSpriteGroup();
04616 act_group = group;
04617
04618 group->num_loaded = num_loaded;
04619 group->num_loading = num_loading;
04620 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
04621 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
04622
04623 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
04624 setid, num_loaded, num_loading);
04625
04626 for (uint i = 0; i < num_loaded; i++) {
04627 uint16 spriteid = buf->ReadWord();
04628 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04629 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
04630 }
04631
04632 for (uint i = 0; i < num_loading; i++) {
04633 uint16 spriteid = buf->ReadWord();
04634 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04635 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
04636 }
04637
04638 break;
04639 }
04640
04641 case GSF_HOUSES:
04642 case GSF_AIRPORTTILES:
04643 case GSF_OBJECTS:
04644 case GSF_INDUSTRYTILES: {
04645 byte num_building_sprites = max((uint8)1, type);
04646
04647 assert(TileLayoutSpriteGroup::CanAllocateItem());
04648 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
04649 act_group = group;
04650
04651
04652 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
04653 break;
04654 }
04655
04656 case GSF_INDUSTRIES: {
04657 if (type > 1) {
04658 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
04659 break;
04660 }
04661
04662 assert(IndustryProductionSpriteGroup::CanAllocateItem());
04663 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04664 act_group = group;
04665 group->version = type;
04666 if (type == 0) {
04667 for (uint i = 0; i < 3; i++) {
04668 group->subtract_input[i] = (int16)buf->ReadWord();
04669 }
04670 for (uint i = 0; i < 2; i++) {
04671 group->add_output[i] = buf->ReadWord();
04672 }
04673 group->again = buf->ReadByte();
04674 } else {
04675 for (uint i = 0; i < 3; i++) {
04676 group->subtract_input[i] = buf->ReadByte();
04677 }
04678 for (uint i = 0; i < 2; i++) {
04679 group->add_output[i] = buf->ReadByte();
04680 }
04681 group->again = buf->ReadByte();
04682 }
04683 break;
04684 }
04685
04686
04687 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04688 }
04689 }
04690 }
04691
04692 _cur.spritegroups[setid] = act_group;
04693 }
04694
04695 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04696 {
04697 if (feature == GSF_OBJECTS) {
04698 switch (ctype) {
04699 case 0: return 0;
04700 case 0xFF: return CT_PURCHASE_OBJECT;
04701 default:
04702 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04703 return CT_INVALID;
04704 }
04705 }
04706
04707 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04708 if (ctype == 0xFF) return CT_PURCHASE;
04709
04710 if (_cur.grffile->cargo_list.Length() == 0) {
04711
04712 if (ctype >= 32) {
04713 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04714 return CT_INVALID;
04715 }
04716
04717 const CargoSpec *cs;
04718 FOR_ALL_CARGOSPECS(cs) {
04719 if (cs->bitnum == ctype) {
04720 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04721 return cs->Index();
04722 }
04723 }
04724
04725 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04726 return CT_INVALID;
04727 }
04728
04729
04730 if (ctype >= _cur.grffile->cargo_list.Length()) {
04731 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
04732 return CT_INVALID;
04733 }
04734
04735
04736 CargoLabel cl = _cur.grffile->cargo_list[ctype];
04737 if (cl == 0) {
04738 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04739 return CT_INVALID;
04740 }
04741
04742 ctype = GetCargoIDByLabel(cl);
04743 if (ctype == CT_INVALID) {
04744 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));
04745 return CT_INVALID;
04746 }
04747
04748 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);
04749 return ctype;
04750 }
04751
04752
04753 static bool IsValidGroupID(uint16 groupid, const char *function)
04754 {
04755 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04756 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
04757 return false;
04758 }
04759
04760 return true;
04761 }
04762
04763 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04764 {
04765 static EngineID *last_engines;
04766 static uint last_engines_count;
04767 bool wagover = false;
04768
04769
04770 if (HasBit(idcount, 7)) {
04771 wagover = true;
04772
04773 idcount = GB(idcount, 0, 7);
04774
04775 if (last_engines_count == 0) {
04776 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04777 return;
04778 }
04779
04780 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04781 last_engines_count, idcount);
04782 } else {
04783 if (last_engines_count != idcount) {
04784 last_engines = ReallocT(last_engines, idcount);
04785 last_engines_count = idcount;
04786 }
04787 }
04788
04789 EngineID *engines = AllocaM(EngineID, idcount);
04790 for (uint i = 0; i < idcount; i++) {
04791 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
04792 if (e == NULL) {
04793
04794
04795
04796 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04797 return;
04798 }
04799
04800 engines[i] = e->index;
04801 if (!wagover) last_engines[i] = engines[i];
04802 }
04803
04804 uint8 cidcount = buf->ReadByte();
04805 for (uint c = 0; c < cidcount; c++) {
04806 uint8 ctype = buf->ReadByte();
04807 uint16 groupid = buf->ReadWord();
04808 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04809
04810 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04811
04812 ctype = TranslateCargo(feature, ctype);
04813 if (ctype == CT_INVALID) continue;
04814
04815 for (uint i = 0; i < idcount; i++) {
04816 EngineID engine = engines[i];
04817
04818 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04819
04820 if (wagover) {
04821 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
04822 } else {
04823 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
04824 }
04825 }
04826 }
04827
04828 uint16 groupid = buf->ReadWord();
04829 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04830
04831 grfmsg(8, "-- Default group id 0x%04X", groupid);
04832
04833 for (uint i = 0; i < idcount; i++) {
04834 EngineID engine = engines[i];
04835
04836 if (wagover) {
04837 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
04838 } else {
04839 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
04840 SetEngineGRF(engine, _cur.grffile);
04841 }
04842 }
04843 }
04844
04845
04846 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04847 {
04848 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04849 for (uint i = 0; i < idcount; i++) {
04850 cfs[i] = (CanalFeature)buf->ReadByte();
04851 }
04852
04853 uint8 cidcount = buf->ReadByte();
04854 buf->Skip(cidcount * 3);
04855
04856 uint16 groupid = buf->ReadWord();
04857 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04858
04859 for (uint i = 0; i < idcount; i++) {
04860 CanalFeature cf = cfs[i];
04861
04862 if (cf >= CF_END) {
04863 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04864 continue;
04865 }
04866
04867 _water_feature[cf].grffile = _cur.grffile;
04868 _water_feature[cf].group = _cur.spritegroups[groupid];
04869 }
04870 }
04871
04872
04873 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04874 {
04875 uint8 *stations = AllocaM(uint8, idcount);
04876 for (uint i = 0; i < idcount; i++) {
04877 stations[i] = buf->ReadByte();
04878 }
04879
04880 uint8 cidcount = buf->ReadByte();
04881 for (uint c = 0; c < cidcount; c++) {
04882 uint8 ctype = buf->ReadByte();
04883 uint16 groupid = buf->ReadWord();
04884 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04885
04886 ctype = TranslateCargo(GSF_STATIONS, ctype);
04887 if (ctype == CT_INVALID) continue;
04888
04889 for (uint i = 0; i < idcount; i++) {
04890 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04891
04892 if (statspec == NULL) {
04893 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04894 continue;
04895 }
04896
04897 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
04898 }
04899 }
04900
04901 uint16 groupid = buf->ReadWord();
04902 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04903
04904 for (uint i = 0; i < idcount; i++) {
04905 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04906
04907 if (statspec == NULL) {
04908 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04909 continue;
04910 }
04911
04912 if (statspec->grf_prop.grffile != NULL) {
04913 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04914 continue;
04915 }
04916
04917 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
04918 statspec->grf_prop.grffile = _cur.grffile;
04919 statspec->grf_prop.local_id = stations[i];
04920 StationClass::Assign(statspec);
04921 }
04922 }
04923
04924
04925 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04926 {
04927 uint8 *houses = AllocaM(uint8, idcount);
04928 for (uint i = 0; i < idcount; i++) {
04929 houses[i] = buf->ReadByte();
04930 }
04931
04932
04933 uint8 cidcount = buf->ReadByte();
04934 buf->Skip(cidcount * 3);
04935
04936 uint16 groupid = buf->ReadWord();
04937 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04938
04939 if (_cur.grffile->housespec == NULL) {
04940 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04941 return;
04942 }
04943
04944 for (uint i = 0; i < idcount; i++) {
04945 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
04946
04947 if (hs == NULL) {
04948 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04949 continue;
04950 }
04951
04952 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04953 }
04954 }
04955
04956 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04957 {
04958 uint8 *industries = AllocaM(uint8, idcount);
04959 for (uint i = 0; i < idcount; i++) {
04960 industries[i] = buf->ReadByte();
04961 }
04962
04963
04964 uint8 cidcount = buf->ReadByte();
04965 buf->Skip(cidcount * 3);
04966
04967 uint16 groupid = buf->ReadWord();
04968 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04969
04970 if (_cur.grffile->industryspec == NULL) {
04971 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04972 return;
04973 }
04974
04975 for (uint i = 0; i < idcount; i++) {
04976 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
04977
04978 if (indsp == NULL) {
04979 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04980 continue;
04981 }
04982
04983 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04984 }
04985 }
04986
04987 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04988 {
04989 uint8 *indtiles = AllocaM(uint8, idcount);
04990 for (uint i = 0; i < idcount; i++) {
04991 indtiles[i] = buf->ReadByte();
04992 }
04993
04994
04995 uint8 cidcount = buf->ReadByte();
04996 buf->Skip(cidcount * 3);
04997
04998 uint16 groupid = buf->ReadWord();
04999 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
05000
05001 if (_cur.grffile->indtspec == NULL) {
05002 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
05003 return;
05004 }
05005
05006 for (uint i = 0; i < idcount; i++) {
05007 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
05008
05009 if (indtsp == NULL) {
05010 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
05011 continue;
05012 }
05013
05014 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05015 }
05016 }
05017
05018 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
05019 {
05020 CargoID *cargoes = AllocaM(CargoID, idcount);
05021 for (uint i = 0; i < idcount; i++) {
05022 cargoes[i] = buf->ReadByte();
05023 }
05024
05025
05026 uint8 cidcount = buf->ReadByte();
05027 buf->Skip(cidcount * 3);
05028
05029 uint16 groupid = buf->ReadWord();
05030 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
05031
05032 for (uint i = 0; i < idcount; i++) {
05033 CargoID cid = cargoes[i];
05034
05035 if (cid >= NUM_CARGO) {
05036 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
05037 continue;
05038 }
05039
05040 CargoSpec *cs = CargoSpec::Get(cid);
05041 cs->grffile = _cur.grffile;
05042 cs->group = _cur.spritegroups[groupid];
05043 }
05044 }
05045
05046 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
05047 {
05048 if (_cur.grffile->objectspec == NULL) {
05049 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
05050 return;
05051 }
05052
05053 uint8 *objects = AllocaM(uint8, idcount);
05054 for (uint i = 0; i < idcount; i++) {
05055 objects[i] = buf->ReadByte();
05056 }
05057
05058 uint8 cidcount = buf->ReadByte();
05059 for (uint c = 0; c < cidcount; c++) {
05060 uint8 ctype = buf->ReadByte();
05061 uint16 groupid = buf->ReadWord();
05062 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
05063
05064 ctype = TranslateCargo(GSF_OBJECTS, ctype);
05065 if (ctype == CT_INVALID) continue;
05066
05067 for (uint i = 0; i < idcount; i++) {
05068 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05069
05070 if (spec == NULL) {
05071 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05072 continue;
05073 }
05074
05075 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
05076 }
05077 }
05078
05079 uint16 groupid = buf->ReadWord();
05080 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
05081
05082 for (uint i = 0; i < idcount; i++) {
05083 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05084
05085 if (spec == NULL) {
05086 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05087 continue;
05088 }
05089
05090 if (spec->grf_prop.grffile != NULL) {
05091 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
05092 continue;
05093 }
05094
05095 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05096 spec->grf_prop.grffile = _cur.grffile;
05097 spec->grf_prop.local_id = objects[i];
05098 }
05099 }
05100
05101 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
05102 {
05103 uint8 *railtypes = AllocaM(uint8, idcount);
05104 for (uint i = 0; i < idcount; i++) {
05105 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
05106 }
05107
05108 uint8 cidcount = buf->ReadByte();
05109 for (uint c = 0; c < cidcount; c++) {
05110 uint8 ctype = buf->ReadByte();
05111 uint16 groupid = buf->ReadWord();
05112 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
05113
05114 if (ctype >= RTSG_END) continue;
05115
05116 extern RailtypeInfo _railtypes[RAILTYPE_END];
05117 for (uint i = 0; i < idcount; i++) {
05118 if (railtypes[i] != INVALID_RAILTYPE) {
05119 RailtypeInfo *rti = &_railtypes[railtypes[i]];
05120
05121 rti->grffile[ctype] = _cur.grffile;
05122 rti->group[ctype] = _cur.spritegroups[groupid];
05123 }
05124 }
05125 }
05126
05127
05128 buf->ReadWord();
05129 }
05130
05131 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
05132 {
05133 uint8 *airports = AllocaM(uint8, idcount);
05134 for (uint i = 0; i < idcount; i++) {
05135 airports[i] = buf->ReadByte();
05136 }
05137
05138
05139 uint8 cidcount = buf->ReadByte();
05140 buf->Skip(cidcount * 3);
05141
05142 uint16 groupid = buf->ReadWord();
05143 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
05144
05145 if (_cur.grffile->airportspec == NULL) {
05146 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
05147 return;
05148 }
05149
05150 for (uint i = 0; i < idcount; i++) {
05151 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
05152
05153 if (as == NULL) {
05154 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
05155 continue;
05156 }
05157
05158 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05159 }
05160 }
05161
05162 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
05163 {
05164 uint8 *airptiles = AllocaM(uint8, idcount);
05165 for (uint i = 0; i < idcount; i++) {
05166 airptiles[i] = buf->ReadByte();
05167 }
05168
05169
05170 uint8 cidcount = buf->ReadByte();
05171 buf->Skip(cidcount * 3);
05172
05173 uint16 groupid = buf->ReadWord();
05174 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
05175
05176 if (_cur.grffile->airtspec == NULL) {
05177 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
05178 return;
05179 }
05180
05181 for (uint i = 0; i < idcount; i++) {
05182 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
05183
05184 if (airtsp == NULL) {
05185 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
05186 continue;
05187 }
05188
05189 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05190 }
05191 }
05192
05193
05194
05195 static void FeatureMapSpriteGroup(ByteReader *buf)
05196 {
05197
05198
05199
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211 uint8 feature = buf->ReadByte();
05212 uint8 idcount = buf->ReadByte();
05213
05214
05215 if (idcount == 0) {
05216
05217 buf->ReadByte();
05218 uint16 groupid = buf->ReadWord();
05219 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
05220
05221 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
05222
05223 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
05224 return;
05225 }
05226
05227
05228 SetBit(_cur.grffile->grf_features, feature);
05229
05230 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
05231
05232 switch (feature) {
05233 case GSF_TRAINS:
05234 case GSF_ROADVEHICLES:
05235 case GSF_SHIPS:
05236 case GSF_AIRCRAFT:
05237 VehicleMapSpriteGroup(buf, feature, idcount);
05238 return;
05239
05240 case GSF_CANALS:
05241 CanalMapSpriteGroup(buf, idcount);
05242 return;
05243
05244 case GSF_STATIONS:
05245 StationMapSpriteGroup(buf, idcount);
05246 return;
05247
05248 case GSF_HOUSES:
05249 TownHouseMapSpriteGroup(buf, idcount);
05250 return;
05251
05252 case GSF_INDUSTRIES:
05253 IndustryMapSpriteGroup(buf, idcount);
05254 return;
05255
05256 case GSF_INDUSTRYTILES:
05257 IndustrytileMapSpriteGroup(buf, idcount);
05258 return;
05259
05260 case GSF_CARGOES:
05261 CargoMapSpriteGroup(buf, idcount);
05262 return;
05263
05264 case GSF_AIRPORTS:
05265 AirportMapSpriteGroup(buf, idcount);
05266 return;
05267
05268 case GSF_OBJECTS:
05269 ObjectMapSpriteGroup(buf, idcount);
05270 break;
05271
05272 case GSF_RAILTYPES:
05273 RailTypeMapSpriteGroup(buf, idcount);
05274 break;
05275
05276 case GSF_AIRPORTTILES:
05277 AirportTileMapSpriteGroup(buf, idcount);
05278 return;
05279
05280 default:
05281 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
05282 return;
05283 }
05284 }
05285
05286
05287 static void FeatureNewName(ByteReader *buf)
05288 {
05289
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305 bool new_scheme = _cur.grffile->grf_version >= 7;
05306
05307 uint8 feature = buf->ReadByte();
05308 uint8 lang = buf->ReadByte();
05309 uint8 num = buf->ReadByte();
05310 bool generic = HasBit(lang, 7);
05311 uint16 id;
05312 if (generic) {
05313 id = buf->ReadWord();
05314 } else if (feature <= GSF_AIRCRAFT) {
05315 id = buf->ReadExtendedByte();
05316 } else {
05317 id = buf->ReadByte();
05318 }
05319
05320 ClrBit(lang, 7);
05321
05322 uint16 endid = id + num;
05323
05324 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
05325 id, endid, feature, lang);
05326
05327 for (; id < endid && buf->HasData(); id++) {
05328 const char *name = buf->ReadString();
05329 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
05330
05331 switch (feature) {
05332 case GSF_TRAINS:
05333 case GSF_ROADVEHICLES:
05334 case GSF_SHIPS:
05335 case GSF_AIRCRAFT:
05336 if (!generic) {
05337 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
05338 if (e == NULL) break;
05339 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
05340 e->info.string_id = string;
05341 } else {
05342 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05343 }
05344 break;
05345
05346 case GSF_INDUSTRIES: {
05347 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05348 break;
05349 }
05350
05351 case GSF_HOUSES:
05352 default:
05353 switch (GB(id, 8, 8)) {
05354 case 0xC4:
05355 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05356 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05357 } else {
05358 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
05359 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05360 }
05361 break;
05362
05363 case 0xC5:
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 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05368 }
05369 break;
05370
05371 case 0xC7:
05372 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
05373 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
05374 } else {
05375 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05376 }
05377 break;
05378
05379 case 0xC9:
05380 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
05381 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
05382 } else {
05383 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05384 }
05385 break;
05386
05387 case 0xD0:
05388 case 0xD1:
05389 case 0xD2:
05390 case 0xD3:
05391 case 0xDC:
05392 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05393 break;
05394
05395 default:
05396 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
05397 break;
05398 }
05399 break;
05400 }
05401 }
05402 }
05403
05412 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
05413 {
05414
05415 if (offset >= max_sprites) {
05416 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
05417 uint orig_num = num;
05418 num = 0;
05419 return orig_num;
05420 }
05421
05422 if (offset + num > max_sprites) {
05423 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
05424 uint orig_num = num;
05425 num = max(max_sprites - offset, 0);
05426 return orig_num - num;
05427 }
05428
05429 return 0;
05430 }
05431
05432
05434 enum Action5BlockType {
05435 A5BLOCK_FIXED,
05436 A5BLOCK_ALLOW_OFFSET,
05437 A5BLOCK_INVALID,
05438 };
05440 struct Action5Type {
05441 Action5BlockType block_type;
05442 SpriteID sprite_base;
05443 uint16 min_sprites;
05444 uint16 max_sprites;
05445 const char *name;
05446 };
05447
05449 static const Action5Type _action5_types[] = {
05450
05451 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
05452 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
05453 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
05454 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
05455 { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
05456 { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
05457 { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
05458 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
05459 { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
05460 { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
05461 { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
05462 { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
05463 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
05464 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
05465 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
05466 { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
05467 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
05468 { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
05469 { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
05470 { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
05471 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
05472 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
05473 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
05474 { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
05475 };
05476
05477
05478 static void GraphicsNew(ByteReader *buf)
05479 {
05480
05481
05482
05483
05484
05485
05486
05487 uint8 type = buf->ReadByte();
05488 uint16 num = buf->ReadExtendedByte();
05489 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
05490 ClrBit(type, 7);
05491
05492 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
05493
05494
05495 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
05496 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05497 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05498 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05499 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05500 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05501 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05502 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05503 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05504 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05505 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
05506 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
05507 return;
05508 }
05509
05510
05511 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
05512 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
05513 _cur.skip_sprites = num;
05514 return;
05515 }
05516
05517 const Action5Type *action5_type = &_action5_types[type];
05518
05519
05520
05521
05522 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
05523 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
05524 offset = 0;
05525 }
05526
05527
05528
05529 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
05530 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);
05531 _cur.skip_sprites = num;
05532 return;
05533 }
05534
05535
05536 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
05537 SpriteID replace = action5_type->sprite_base + offset;
05538
05539
05540 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);
05541
05542 for (; num > 0; num--) {
05543 _cur.nfo_line++;
05544 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
05545 }
05546
05547 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
05548
05549 _cur.skip_sprites = skip_num;
05550 }
05551
05552
05553 static void SkipAct5(ByteReader *buf)
05554 {
05555
05556 buf->ReadByte();
05557
05558
05559 _cur.skip_sprites = buf->ReadExtendedByte();
05560
05561 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
05562 }
05563
05569 void CheckForMissingSprites()
05570 {
05571
05572
05573 bool missing = false;
05574 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
05575 const Action5Type *type = &_action5_types[i];
05576 if (type->block_type == A5BLOCK_INVALID) continue;
05577
05578 for (uint j = 0; j < type->max_sprites; j++) {
05579 if (!SpriteExists(type->sprite_base + j)) {
05580 DEBUG(grf, 0, "%s sprites are missing", type->name);
05581 missing = true;
05582
05583 break;
05584 }
05585 }
05586 }
05587
05588 if (missing) {
05589 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
05590 }
05591 }
05592
05604 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
05605 {
05606 switch (param) {
05607 case 0x00:
05608 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
05609 return true;
05610
05611 case 0x01:
05612 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
05613 return true;
05614
05615 case 0x02: {
05616 YearMonthDay ymd;
05617 ConvertDateToYMD(_date, &ymd);
05618 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
05619 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
05620 return true;
05621 }
05622
05623 case 0x03:
05624 *value = _settings_game.game_creation.landscape;
05625 return true;
05626
05627 case 0x06:
05628 *value = _settings_game.vehicle.road_side << 4;
05629 return true;
05630
05631 case 0x09:
05632 *value = _date_fract * 885;
05633 return true;
05634
05635 case 0x0A:
05636 *value = _tick_counter;
05637 return true;
05638
05639 case 0x0B: {
05640 uint major = 2;
05641 uint minor = 6;
05642 uint revision = 1;
05643 uint build = 1382;
05644 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05645 return true;
05646 }
05647
05648 case 0x0D:
05649 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
05650 return true;
05651
05652 case 0x0E:
05653 *value = _cur.grffile->traininfo_vehicle_pitch;
05654 return true;
05655
05656 case 0x0F:
05657 *value = 0;
05658 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
05659 if (_settings_game.vehicle.disable_elrails) {
05660
05661 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05662 } else {
05663 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05664
05665 }
05666 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05667 return true;
05668
05669 case 0x11:
05670 *value = 0;
05671 return true;
05672
05673 case 0x12:
05674 *value = _game_mode;
05675 return true;
05676
05677
05678
05679
05680
05681
05682
05683 case 0x1A:
05684 *value = UINT_MAX;
05685 return true;
05686
05687 case 0x1B:
05688 *value = 0x3F;
05689 return true;
05690
05691 case 0x1D:
05692 *value = 1;
05693 return true;
05694
05695 case 0x1E:
05696 *value = _misc_grf_features;
05697
05698
05699 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05700 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05701 return true;
05702
05703
05704
05705 case 0x20: {
05706 byte snowline = GetSnowLine();
05707 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
05708 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
05709 } else {
05710
05711 *value = 0xFF;
05712 }
05713 return true;
05714 }
05715
05716 case 0x21:
05717 *value = _openttd_newgrf_version;
05718 return true;
05719
05720 case 0x22:
05721 *value = _settings_game.difficulty.diff_level;
05722 return true;
05723
05724 case 0x23:
05725 *value = _date;
05726 return true;
05727
05728 case 0x24:
05729 *value = _cur_year;
05730 return true;
05731
05732 default: return false;
05733 }
05734 }
05735
05736 static uint32 GetParamVal(byte param, uint32 *cond_val)
05737 {
05738
05739 uint32 value;
05740 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
05741
05742
05743 switch (param) {
05744 case 0x84: {
05745 uint32 res = 0;
05746
05747 if (_cur.stage > GLS_INIT) SetBit(res, 0);
05748 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
05749 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
05750 return res;
05751 }
05752
05753 case 0x85:
05754 if (cond_val == NULL) {
05755
05756 return 0;
05757 } else {
05758 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05759 *cond_val %= 0x20;
05760 return param_val;
05761 }
05762
05763 case 0x88:
05764 return 0;
05765
05766
05767
05768 default:
05769
05770 if (param < 0x80) return _cur.grffile->GetParam(param);
05771
05772
05773 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05774 return UINT_MAX;
05775 }
05776 }
05777
05778
05779 static void CfgApply(ByteReader *buf)
05780 {
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793 size_t pos = FioGetPos();
05794 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
05795 uint8 type = FioReadByte();
05796 byte *preload_sprite = NULL;
05797
05798
05799 if (type == 0xFF) {
05800 preload_sprite = MallocT<byte>(num);
05801 FioReadBlock(preload_sprite, num);
05802 }
05803
05804
05805 FioSeekTo(pos, SEEK_SET);
05806
05807 if (type != 0xFF) {
05808 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05809 free(preload_sprite);
05810 return;
05811 }
05812
05813 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
05814 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05815 if (it != _grf_line_to_action6_sprite_override.end()) {
05816 free(preload_sprite);
05817 preload_sprite = _grf_line_to_action6_sprite_override[location];
05818 } else {
05819 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05820 }
05821
05822
05823
05824 for (;;) {
05825 uint i;
05826 uint param_num;
05827 uint param_size;
05828 uint offset;
05829 bool add_value;
05830
05831
05832 param_num = buf->ReadByte();
05833 if (param_num == 0xFF) break;
05834
05835
05836
05837 param_size = buf->ReadByte();
05838
05839
05840
05841 add_value = HasBit(param_size, 7);
05842 param_size = GB(param_size, 0, 7);
05843
05844
05845 offset = buf->ReadExtendedByte();
05846
05847
05848
05849 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
05850 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05851 break;
05852 }
05853
05854 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05855
05856 bool carry = false;
05857 for (i = 0; i < param_size && offset + i < num; i++) {
05858 uint32 value = GetParamVal(param_num + i / 4, NULL);
05859
05860
05861 if (i % 4 == 0) carry = false;
05862
05863 if (add_value) {
05864 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05865 preload_sprite[offset + i] = GB(new_value, 0, 8);
05866
05867 carry = new_value >= 256;
05868 } else {
05869 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05870 }
05871 }
05872 }
05873 }
05874
05884 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05885 {
05886 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05887 error->data = strdup(_cur.grfconfig->GetName());
05888 }
05889
05890
05891
05892 static void SkipIf(ByteReader *buf)
05893 {
05894
05895
05896
05897
05898
05899
05900
05901
05902 uint32 cond_val = 0;
05903 uint32 mask = 0;
05904 bool result;
05905
05906 uint8 param = buf->ReadByte();
05907 uint8 paramsize = buf->ReadByte();
05908 uint8 condtype = buf->ReadByte();
05909
05910 if (condtype < 2) {
05911
05912 paramsize = 1;
05913 }
05914
05915 switch (paramsize) {
05916 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05917 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05918 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05919 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05920 default: break;
05921 }
05922
05923 if (param < 0x80 && _cur.grffile->param_end <= param) {
05924 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05925 return;
05926 }
05927
05928 uint32 param_val = GetParamVal(param, &cond_val);
05929
05930 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05941
05942
05943 GRFConfig *c = GetGRFConfig(cond_val, mask);
05944
05945 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
05946 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05947 c = NULL;
05948 }
05949
05950 if (condtype != 10 && c == NULL) {
05951 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05952 return;
05953 }
05954
05955 switch (condtype) {
05956
05957 case 0x06:
05958 result = c->status == GCS_ACTIVATED;
05959 break;
05960
05961 case 0x07:
05962 result = c->status != GCS_ACTIVATED;
05963 break;
05964
05965 case 0x08:
05966 result = c->status == GCS_INITIALISED;
05967 break;
05968
05969 case 0x09:
05970 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05971 break;
05972
05973 case 0x0A:
05974
05975 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05976 break;
05977
05978 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05979 }
05980 } else {
05981
05982 switch (condtype) {
05983 case 0x00: result = !!(param_val & (1 << cond_val));
05984 break;
05985 case 0x01: result = !(param_val & (1 << cond_val));
05986 break;
05987 case 0x02: result = (param_val & mask) == cond_val;
05988 break;
05989 case 0x03: result = (param_val & mask) != cond_val;
05990 break;
05991 case 0x04: result = (param_val & mask) < cond_val;
05992 break;
05993 case 0x05: result = (param_val & mask) > cond_val;
05994 break;
05995 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05996 break;
05997 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05998 break;
05999 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
06000 break;
06001 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
06002 break;
06003
06004 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
06005 }
06006 }
06007
06008 if (!result) {
06009 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
06010 return;
06011 }
06012
06013 uint8 numsprites = buf->ReadByte();
06014
06015
06016
06017
06018
06019 GRFLabel *choice = NULL;
06020 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
06021 if (label->label != numsprites) continue;
06022
06023
06024 if (choice == NULL) choice = label;
06025
06026 if (label->nfo_line > _cur.nfo_line) {
06027 choice = label;
06028 break;
06029 }
06030 }
06031
06032 if (choice != NULL) {
06033 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
06034 FioSeekTo(choice->pos, SEEK_SET);
06035 _cur.nfo_line = choice->nfo_line;
06036 return;
06037 }
06038
06039 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
06040 _cur.skip_sprites = numsprites;
06041 if (_cur.skip_sprites == 0) {
06042
06043
06044
06045 _cur.skip_sprites = -1;
06046
06047
06048 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
06049 DisableGrf();
06050 }
06051 }
06052 }
06053
06054
06055
06056 static void ScanInfo(ByteReader *buf)
06057 {
06058 uint8 grf_version = buf->ReadByte();
06059 uint32 grfid = buf->ReadDWord();
06060 const char *name = buf->ReadString();
06061
06062 _cur.grfconfig->ident.grfid = grfid;
06063
06064 if (grf_version < 2 || grf_version > 8) {
06065 SetBit(_cur.grfconfig->flags, GCF_INVALID);
06066 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);
06067 }
06068
06069
06070 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
06071
06072 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
06073
06074 if (buf->HasData()) {
06075 const char *info = buf->ReadString();
06076 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
06077 }
06078
06079
06080 _cur.skip_sprites = -1;
06081 }
06082
06083
06084 static void GRFInfo(ByteReader *buf)
06085 {
06086
06087
06088
06089
06090
06091
06092
06093 uint8 version = buf->ReadByte();
06094 uint32 grfid = buf->ReadDWord();
06095 const char *name = buf->ReadString();
06096
06097 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
06098 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
06099 return;
06100 }
06101
06102 if (_cur.grffile->grfid != grfid) {
06103 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));
06104 _cur.grffile->grfid = grfid;
06105 }
06106
06107 _cur.grffile->grf_version = version;
06108 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
06109
06110
06111 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);
06112 }
06113
06114
06115 static void SpriteReplace(ByteReader *buf)
06116 {
06117
06118
06119
06120
06121
06122
06123
06124
06125 uint8 num_sets = buf->ReadByte();
06126
06127 for (uint i = 0; i < num_sets; i++) {
06128 uint8 num_sprites = buf->ReadByte();
06129 uint16 first_sprite = buf->ReadWord();
06130
06131 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
06132 i, num_sprites, first_sprite
06133 );
06134
06135 for (uint j = 0; j < num_sprites; j++) {
06136 int load_index = first_sprite + j;
06137 _cur.nfo_line++;
06138 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
06139
06140
06141
06142 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
06143 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06144 }
06145 }
06146 }
06147 }
06148
06149
06150 static void SkipActA(ByteReader *buf)
06151 {
06152 uint8 num_sets = buf->ReadByte();
06153
06154 for (uint i = 0; i < num_sets; i++) {
06155
06156 _cur.skip_sprites += buf->ReadByte();
06157
06158 buf->ReadWord();
06159 }
06160
06161 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
06162 }
06163
06164
06165 static void GRFLoadError(ByteReader *buf)
06166 {
06167
06168
06169
06170
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182 static const StringID msgstr[] = {
06183 STR_NEWGRF_ERROR_VERSION_NUMBER,
06184 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
06185 STR_NEWGRF_ERROR_UNSET_SWITCH,
06186 STR_NEWGRF_ERROR_INVALID_PARAMETER,
06187 STR_NEWGRF_ERROR_LOAD_BEFORE,
06188 STR_NEWGRF_ERROR_LOAD_AFTER,
06189 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
06190 };
06191
06192 static const StringID sevstr[] = {
06193 STR_NEWGRF_ERROR_MSG_INFO,
06194 STR_NEWGRF_ERROR_MSG_WARNING,
06195 STR_NEWGRF_ERROR_MSG_ERROR,
06196 STR_NEWGRF_ERROR_MSG_FATAL
06197 };
06198
06199 byte severity = buf->ReadByte();
06200 byte lang = buf->ReadByte();
06201 byte message_id = buf->ReadByte();
06202
06203
06204 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
06205
06206
06207
06208 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
06209 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
06210 return;
06211 }
06212 ClrBit(severity, 7);
06213
06214 if (severity >= lengthof(sevstr)) {
06215 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
06216 severity = 2;
06217 } else if (severity == 3) {
06218
06219
06220 DisableGrf();
06221
06222
06223 delete _cur.grfconfig->error;
06224 _cur.grfconfig->error = NULL;
06225 }
06226
06227 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
06228 grfmsg(7, "GRFLoadError: Invalid message id.");
06229 return;
06230 }
06231
06232 if (buf->Remaining() <= 1) {
06233 grfmsg(7, "GRFLoadError: No message data supplied.");
06234 return;
06235 }
06236
06237
06238 if (_cur.grfconfig->error != NULL) return;
06239
06240 GRFError *error = new GRFError(sevstr[severity]);
06241
06242 if (message_id == 0xFF) {
06243
06244 if (buf->HasData()) {
06245 const char *message = buf->ReadString();
06246
06247 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
06248 } else {
06249 grfmsg(7, "GRFLoadError: No custom message supplied.");
06250 error->custom_message = strdup("");
06251 }
06252 } else {
06253 error->message = msgstr[message_id];
06254 }
06255
06256 if (buf->HasData()) {
06257 const char *data = buf->ReadString();
06258
06259 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
06260 } else {
06261 grfmsg(7, "GRFLoadError: No message data supplied.");
06262 error->data = strdup("");
06263 }
06264
06265
06266 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
06267 uint param_number = buf->ReadByte();
06268 error->param_value[i] = _cur.grffile->GetParam(param_number);
06269 }
06270
06271 _cur.grfconfig->error = error;
06272 }
06273
06274
06275 static void GRFComment(ByteReader *buf)
06276 {
06277
06278
06279
06280
06281 if (!buf->HasData()) return;
06282
06283 const char *text = buf->ReadString();
06284 grfmsg(2, "GRFComment: %s", text);
06285 }
06286
06287
06288 static void SafeParamSet(ByteReader *buf)
06289 {
06290 uint8 target = buf->ReadByte();
06291
06292
06293 if (target < 0x80) return;
06294
06295
06296
06297
06298
06299
06300 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06301
06302
06303 _cur.skip_sprites = -1;
06304 }
06305
06306
06307 static uint32 GetPatchVariable(uint8 param)
06308 {
06309 switch (param) {
06310
06311 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
06312
06313
06314 case 0x0E: return _settings_game.vehicle.freight_trains;
06315
06316
06317 case 0x0F: return 0;
06318
06319
06320
06321
06322 case 0x10:
06323 switch (_settings_game.vehicle.plane_speed) {
06324 default:
06325 case 4: return 1;
06326 case 3: return 2;
06327 case 2: return 2;
06328 case 1: return 4;
06329 }
06330
06331
06332
06333 case 0x11: return SPR_2CCMAP_BASE;
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343
06344
06345
06346 case 0x13: {
06347 byte map_bits = 0;
06348 byte log_X = MapLogX() - 6;
06349 byte log_Y = MapLogY() - 6;
06350 byte max_edge = max(log_X, log_Y);
06351
06352 if (log_X == log_Y) {
06353 SetBit(map_bits, 0);
06354 } else {
06355 if (max_edge == log_Y) SetBit(map_bits, 1);
06356 }
06357
06358 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
06359 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
06360 }
06361
06362
06363 case 0x14:
06364 return MAX_TILE_HEIGHT;
06365
06366 default:
06367 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
06368 return 0;
06369 }
06370 }
06371
06372
06373 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
06374 {
06375 uint start = 0;
06376 uint size = 0;
06377
06378 if (op == 6) {
06379
06380 return grm[_cur.grffile->GetParam(target)];
06381 }
06382
06383
06384 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
06385
06386 for (uint i = start; i < num_ids; i++) {
06387 if (grm[i] == 0) {
06388 size++;
06389 } else {
06390 if (op == 2 || op == 3) break;
06391 start = i + 1;
06392 size = 0;
06393 }
06394
06395 if (size == count) break;
06396 }
06397
06398 if (size == count) {
06399
06400 if (op == 0 || op == 3) {
06401 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
06402 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
06403 }
06404 return start;
06405 }
06406
06407
06408 if (op != 4 && op != 5) {
06409
06410 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
06411 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06412 return UINT_MAX;
06413 }
06414
06415 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
06416 return UINT_MAX;
06417 }
06418
06419
06421 static void ParamSet(ByteReader *buf)
06422 {
06423
06424
06425
06426
06427
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445 uint8 target = buf->ReadByte();
06446 uint8 oper = buf->ReadByte();
06447 uint32 src1 = buf->ReadByte();
06448 uint32 src2 = buf->ReadByte();
06449
06450 uint32 data = 0;
06451 if (buf->Remaining() >= 4) data = buf->ReadDWord();
06452
06453
06454
06455
06456
06457
06458
06459 if (HasBit(oper, 7)) {
06460 if (target < 0x80 && target < _cur.grffile->param_end) {
06461 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
06462 return;
06463 }
06464
06465 oper = GB(oper, 0, 7);
06466 }
06467
06468 if (src2 == 0xFE) {
06469 if (GB(data, 0, 8) == 0xFF) {
06470 if (data == 0x0000FFFF) {
06471
06472 src1 = GetPatchVariable(src1);
06473 } else {
06474
06475 uint8 op = src1;
06476 uint8 feature = GB(data, 8, 8);
06477 uint16 count = GB(data, 16, 16);
06478
06479 if (_cur.stage == GLS_RESERVE) {
06480 if (feature == 0x08) {
06481
06482 if (op == 0) {
06483
06484 if (_cur.spriteid + count >= 16384) {
06485 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
06486 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06487 return;
06488 }
06489
06490
06491 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
06492 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
06493 _cur.spriteid += count;
06494 }
06495 }
06496
06497 src1 = 0;
06498 } else if (_cur.stage == GLS_ACTIVATION) {
06499 switch (feature) {
06500 case 0x00:
06501 case 0x01:
06502 case 0x02:
06503 case 0x03:
06504 if (!_settings_game.vehicle.dynamic_engines) {
06505 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
06506 if (_cur.skip_sprites == -1) return;
06507 } else {
06508
06509 switch (op) {
06510 case 2:
06511 case 3:
06512 src1 = _cur.grffile->GetParam(target);
06513 break;
06514
06515 default:
06516 src1 = 0;
06517 break;
06518 }
06519 }
06520 break;
06521
06522 case 0x08:
06523 switch (op) {
06524 case 0:
06525
06526 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
06527 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
06528 break;
06529
06530 case 1:
06531 src1 = _cur.spriteid;
06532 break;
06533
06534 default:
06535 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
06536 return;
06537 }
06538 break;
06539
06540 case 0x0B:
06541
06542 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
06543 if (_cur.skip_sprites == -1) return;
06544 break;
06545
06546 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
06547 }
06548 } else {
06549
06550 src1 = 0;
06551 }
06552 }
06553 } else {
06554
06555 const GRFFile *file = GetFileByGRFID(data);
06556 GRFConfig *c = GetGRFConfig(data);
06557 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
06558
06559 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
06560 src1 = 0;
06561 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
06562 src1 = 0;
06563 } else if (src1 == 0xFE) {
06564 src1 = c->version;
06565 } else {
06566 src1 = file->GetParam(src1);
06567 }
06568 }
06569 } else {
06570
06571
06572
06573
06574
06575 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
06576 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
06577 }
06578
06579
06580
06581
06582
06583
06584
06585 uint32 res;
06586 switch (oper) {
06587 case 0x00:
06588 res = src1;
06589 break;
06590
06591 case 0x01:
06592 res = src1 + src2;
06593 break;
06594
06595 case 0x02:
06596 res = src1 - src2;
06597 break;
06598
06599 case 0x03:
06600 res = src1 * src2;
06601 break;
06602
06603 case 0x04:
06604 res = (int32)src1 * (int32)src2;
06605 break;
06606
06607 case 0x05:
06608 if ((int32)src2 < 0) {
06609 res = src1 >> -(int32)src2;
06610 } else {
06611 res = src1 << src2;
06612 }
06613 break;
06614
06615 case 0x06:
06616 if ((int32)src2 < 0) {
06617 res = (int32)src1 >> -(int32)src2;
06618 } else {
06619 res = (int32)src1 << src2;
06620 }
06621 break;
06622
06623 case 0x07:
06624 res = src1 & src2;
06625 break;
06626
06627 case 0x08:
06628 res = src1 | src2;
06629 break;
06630
06631 case 0x09:
06632 if (src2 == 0) {
06633 res = src1;
06634 } else {
06635 res = src1 / src2;
06636 }
06637 break;
06638
06639 case 0x0A:
06640 if (src2 == 0) {
06641 res = src1;
06642 } else {
06643 res = (int32)src1 / (int32)src2;
06644 }
06645 break;
06646
06647 case 0x0B:
06648 if (src2 == 0) {
06649 res = src1;
06650 } else {
06651 res = src1 % src2;
06652 }
06653 break;
06654
06655 case 0x0C:
06656 if (src2 == 0) {
06657 res = src1;
06658 } else {
06659 res = (int32)src1 % (int32)src2;
06660 }
06661 break;
06662
06663 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06664 }
06665
06666 switch (target) {
06667 case 0x8E:
06668 _cur.grffile->traininfo_vehicle_pitch = res;
06669 break;
06670
06671 case 0x8F: {
06672 extern RailtypeInfo _railtypes[RAILTYPE_END];
06673 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06674 if (_settings_game.vehicle.disable_elrails) {
06675 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06676 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06677 } else {
06678 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06679 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06680 }
06681 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06682 break;
06683 }
06684
06685
06686 case 0x93:
06687 case 0x94:
06688 case 0x95:
06689 case 0x96:
06690 case 0x97:
06691 case 0x99:
06692 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06693 break;
06694
06695 case 0x9E:
06696
06697 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06698
06699 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
06700
06701 _misc_grf_features = res;
06702 break;
06703
06704 case 0x9F:
06705 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06706 break;
06707
06708 default:
06709 if (target < 0x80) {
06710 _cur.grffile->param[target] = res;
06711
06712 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
06713 } else {
06714 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06715 }
06716 break;
06717 }
06718 }
06719
06720
06721 static void SafeGRFInhibit(ByteReader *buf)
06722 {
06723
06724
06725
06726
06727
06728 uint8 num = buf->ReadByte();
06729
06730 for (uint i = 0; i < num; i++) {
06731 uint32 grfid = buf->ReadDWord();
06732
06733
06734 if (grfid != _cur.grfconfig->ident.grfid) {
06735 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06736
06737
06738 _cur.skip_sprites = -1;
06739
06740 return;
06741 }
06742 }
06743 }
06744
06745
06746 static void GRFInhibit(ByteReader *buf)
06747 {
06748
06749
06750
06751
06752
06753 uint8 num = buf->ReadByte();
06754
06755 for (uint i = 0; i < num; i++) {
06756 uint32 grfid = buf->ReadDWord();
06757 GRFConfig *file = GetGRFConfig(grfid);
06758
06759
06760 if (file != NULL && file != _cur.grfconfig) {
06761 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06762 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06763 error->data = strdup(_cur.grfconfig->GetName());
06764 }
06765 }
06766 }
06767
06769 static void FeatureTownName(ByteReader *buf)
06770 {
06771
06772
06773
06774
06775
06776
06777
06778 uint32 grfid = _cur.grffile->grfid;
06779
06780 GRFTownName *townname = AddGRFTownName(grfid);
06781
06782 byte id = buf->ReadByte();
06783 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06784
06785 if (HasBit(id, 7)) {
06786
06787 ClrBit(id, 7);
06788 bool new_scheme = _cur.grffile->grf_version >= 7;
06789
06790 byte lang = buf->ReadByte();
06791
06792 byte nb_gen = townname->nb_gen;
06793 do {
06794 ClrBit(lang, 7);
06795
06796 const char *name = buf->ReadString();
06797
06798 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06799 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06800 free(lang_name);
06801
06802 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06803
06804 lang = buf->ReadByte();
06805 } while (lang != 0);
06806 townname->id[nb_gen] = id;
06807 townname->nb_gen++;
06808 }
06809
06810 byte nb = buf->ReadByte();
06811 grfmsg(6, "FeatureTownName: %u parts", nb);
06812
06813 townname->nbparts[id] = nb;
06814 townname->partlist[id] = CallocT<NamePartList>(nb);
06815
06816 for (int i = 0; i < nb; i++) {
06817 byte nbtext = buf->ReadByte();
06818 townname->partlist[id][i].bitstart = buf->ReadByte();
06819 townname->partlist[id][i].bitcount = buf->ReadByte();
06820 townname->partlist[id][i].maxprob = 0;
06821 townname->partlist[id][i].partcount = nbtext;
06822 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06823 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);
06824
06825 for (int j = 0; j < nbtext; j++) {
06826 byte prob = buf->ReadByte();
06827
06828 if (HasBit(prob, 7)) {
06829 byte ref_id = buf->ReadByte();
06830
06831 if (townname->nbparts[ref_id] == 0) {
06832 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06833 DelGRFTownName(grfid);
06834 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06835 return;
06836 }
06837
06838 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06839 townname->partlist[id][i].parts[j].data.id = ref_id;
06840 } else {
06841 const char *text = buf->ReadString();
06842 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06843 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06844 }
06845 townname->partlist[id][i].parts[j].prob = prob;
06846 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06847 }
06848 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06849 }
06850 }
06851
06853 static void DefineGotoLabel(ByteReader *buf)
06854 {
06855
06856
06857
06858
06859
06860 byte nfo_label = buf->ReadByte();
06861
06862 GRFLabel *label = MallocT<GRFLabel>(1);
06863 label->label = nfo_label;
06864 label->nfo_line = _cur.nfo_line;
06865 label->pos = FioGetPos();
06866 label->next = NULL;
06867
06868
06869 if (_cur.grffile->label == NULL) {
06870 _cur.grffile->label = label;
06871 } else {
06872
06873 GRFLabel *l;
06874 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
06875 l->next = label;
06876 }
06877
06878 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06879 }
06880
06885 static void ImportGRFSound(SoundEntry *sound)
06886 {
06887 const GRFFile *file;
06888 uint32 grfid = FioReadDword();
06889 SoundID sound_id = FioReadWord();
06890
06891 file = GetFileByGRFID(grfid);
06892 if (file == NULL || file->sound_offset == 0) {
06893 grfmsg(1, "ImportGRFSound: Source file not available");
06894 return;
06895 }
06896
06897 if (sound_id >= file->num_sounds) {
06898 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06899 return;
06900 }
06901
06902 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06903
06904 *sound = *GetSound(file->sound_offset + sound_id);
06905
06906
06907 sound->volume = 128;
06908 sound->priority = 0;
06909 }
06910
06916 static void LoadGRFSound(size_t offs, SoundEntry *sound)
06917 {
06918
06919 sound->volume = 0x80;
06920 sound->priority = 0;
06921
06922 if (offs != SIZE_MAX) {
06923
06924 sound->file_slot = _cur.file_index;
06925 sound->file_offset = offs;
06926 sound->grf_container_ver = _cur.grf_container_ver;
06927 }
06928 }
06929
06930
06931 static void GRFSound(ByteReader *buf)
06932 {
06933
06934
06935
06936
06937 uint16 num = buf->ReadWord();
06938 if (num == 0) return;
06939
06940 SoundEntry *sound;
06941 if (_cur.grffile->sound_offset == 0) {
06942 _cur.grffile->sound_offset = GetNumSounds();
06943 _cur.grffile->num_sounds = num;
06944 sound = AllocateSound(num);
06945 } else {
06946 sound = GetSound(_cur.grffile->sound_offset);
06947 }
06948
06949 for (int i = 0; i < num; i++) {
06950 _cur.nfo_line++;
06951
06952
06953
06954 bool invalid = i >= _cur.grffile->num_sounds;
06955
06956 size_t offs = FioGetPos();
06957
06958 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
06959 byte type = FioReadByte();
06960
06961 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
06962
06963 if (invalid) {
06964 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06965 FioSkipBytes(len);
06966 } else if (len != 4) {
06967 grfmsg(1, "GRFSound: Invalid sprite section import");
06968 FioSkipBytes(len);
06969 } else {
06970 uint32 id = FioReadDword();
06971 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
06972 }
06973 continue;
06974 }
06975
06976 if (type != 0xFF) {
06977 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
06978 FioSkipBytes(7);
06979 SkipSpriteData(type, len - 8);
06980 continue;
06981 }
06982
06983 if (invalid) {
06984 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
06985 FioSkipBytes(len);
06986 }
06987
06988 byte action = FioReadByte();
06989 switch (action) {
06990 case 0xFF:
06991
06992 if (_cur.stage == GLS_INIT) {
06993 if (_cur.grf_container_ver >= 2) {
06994 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
06995 } else {
06996 LoadGRFSound(offs, sound + i);
06997 }
06998 }
06999 FioSkipBytes(len - 1);
07000 break;
07001
07002 case 0xFE:
07003 if (_cur.stage == GLS_ACTIVATION) {
07004
07005
07006 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
07007 ImportGRFSound(sound + i);
07008 } else {
07009 FioSkipBytes(len - 1);
07010 }
07011 break;
07012
07013 default:
07014 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
07015 FioSkipBytes(len - 1);
07016 break;
07017 }
07018 }
07019 }
07020
07021
07022 static void SkipAct11(ByteReader *buf)
07023 {
07024
07025
07026
07027
07028 _cur.skip_sprites = buf->ReadWord();
07029
07030 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
07031 }
07032
07034 static void LoadFontGlyph(ByteReader *buf)
07035 {
07036
07037
07038
07039
07040
07041
07042
07043 uint8 num_def = buf->ReadByte();
07044
07045 for (uint i = 0; i < num_def; i++) {
07046 FontSize size = (FontSize)buf->ReadByte();
07047 uint8 num_char = buf->ReadByte();
07048 uint16 base_char = buf->ReadWord();
07049
07050 if (size >= FS_END) {
07051 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
07052 }
07053
07054 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
07055
07056 for (uint c = 0; c < num_char; c++) {
07057 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
07058 _cur.nfo_line++;
07059 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
07060 }
07061 }
07062 }
07063
07065 static void SkipAct12(ByteReader *buf)
07066 {
07067
07068
07069
07070
07071
07072
07073
07074 uint8 num_def = buf->ReadByte();
07075
07076 for (uint i = 0; i < num_def; i++) {
07077
07078 buf->ReadByte();
07079
07080
07081 _cur.skip_sprites += buf->ReadByte();
07082
07083
07084 buf->ReadWord();
07085 }
07086
07087 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
07088 }
07089
07091 static void TranslateGRFStrings(ByteReader *buf)
07092 {
07093
07094
07095
07096
07097
07098
07099
07100 uint32 grfid = buf->ReadDWord();
07101 const GRFConfig *c = GetGRFConfig(grfid);
07102 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
07103 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
07104 return;
07105 }
07106
07107 if (c->status == GCS_INITIALISED) {
07108
07109
07110 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
07111
07112 char tmp[256];
07113 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
07114 error->data = strdup(tmp);
07115
07116 return;
07117 }
07118
07119
07120
07121
07122
07123
07124 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
07125 byte num_strings = buf->ReadByte();
07126 uint16 first_id = buf->ReadWord();
07127
07128 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
07129 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
07130 return;
07131 }
07132
07133 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
07134 const char *string = buf->ReadString();
07135
07136 if (StrEmpty(string)) {
07137 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
07138 continue;
07139 }
07140
07141 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
07142 }
07143 }
07144
07146 static bool ChangeGRFName(byte langid, const char *str)
07147 {
07148 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
07149 return true;
07150 }
07151
07153 static bool ChangeGRFDescription(byte langid, const char *str)
07154 {
07155 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
07156 return true;
07157 }
07158
07160 static bool ChangeGRFURL(byte langid, const char *str)
07161 {
07162 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
07163 return true;
07164 }
07165
07167 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
07168 {
07169 if (len != 1) {
07170 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
07171 buf->Skip(len);
07172 } else {
07173 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
07174 }
07175 return true;
07176 }
07177
07179 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
07180 {
07181 if (len != 1) {
07182 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
07183 buf->Skip(len);
07184 } else {
07185 char data = buf->ReadByte();
07186 GRFPalette pal = GRFP_GRF_UNSET;
07187 switch (data) {
07188 case '*':
07189 case 'A': pal = GRFP_GRF_ANY; break;
07190 case 'W': pal = GRFP_GRF_WINDOWS; break;
07191 case 'D': pal = GRFP_GRF_DOS; break;
07192 default:
07193 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
07194 break;
07195 }
07196 if (pal != GRFP_GRF_UNSET) {
07197 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
07198 _cur.grfconfig->palette |= pal;
07199 }
07200 }
07201 return true;
07202 }
07203
07205 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
07206 {
07207 if (len != 1) {
07208 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
07209 buf->Skip(len);
07210 } else {
07211 char data = buf->ReadByte();
07212 GRFPalette pal = GRFP_BLT_UNSET;
07213 switch (data) {
07214 case '8': pal = GRFP_BLT_UNSET; break;
07215 case '3': pal = GRFP_BLT_32BPP; break;
07216 default:
07217 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
07218 return true;
07219 }
07220 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
07221 _cur.grfconfig->palette |= pal;
07222 }
07223 return true;
07224 }
07225
07227 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
07228 {
07229 if (len != 4) {
07230 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
07231 buf->Skip(len);
07232 } else {
07233
07234 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07235 }
07236 return true;
07237 }
07238
07240 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
07241 {
07242 if (len != 4) {
07243 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
07244 buf->Skip(len);
07245 } else {
07246 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07247 if (_cur.grfconfig->version == 0) {
07248 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
07249 _cur.grfconfig->min_loadable_version = 0;
07250 }
07251 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
07252 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
07253 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
07254 }
07255 }
07256 return true;
07257 }
07258
07259 static GRFParameterInfo *_cur_parameter;
07260
07262 static bool ChangeGRFParamName(byte langid, const char *str)
07263 {
07264 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
07265 return true;
07266 }
07267
07269 static bool ChangeGRFParamDescription(byte langid, const char *str)
07270 {
07271 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
07272 return true;
07273 }
07274
07276 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
07277 {
07278 if (len != 1) {
07279 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
07280 buf->Skip(len);
07281 } else {
07282 GRFParameterType type = (GRFParameterType)buf->ReadByte();
07283 if (type < PTYPE_END) {
07284 _cur_parameter->type = type;
07285 } else {
07286 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
07287 }
07288 }
07289 return true;
07290 }
07291
07293 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
07294 {
07295 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
07296 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
07297 buf->Skip(len);
07298 } else if (len != 8) {
07299 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
07300 buf->Skip(len);
07301 } else {
07302 _cur_parameter->min_value = buf->ReadDWord();
07303 _cur_parameter->max_value = buf->ReadDWord();
07304 }
07305 return true;
07306 }
07307
07309 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
07310 {
07311 if (len < 1 || len > 3) {
07312 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
07313 buf->Skip(len);
07314 } else {
07315 byte param_nr = buf->ReadByte();
07316 if (param_nr >= lengthof(_cur.grfconfig->param)) {
07317 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
07318 buf->Skip(len - 1);
07319 } else {
07320 _cur_parameter->param_nr = param_nr;
07321 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
07322 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
07323 }
07324 }
07325
07326 return true;
07327 }
07328
07330 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
07331 {
07332 if (len != 4) {
07333 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
07334 buf->Skip(len);
07335 } else {
07336 _cur_parameter->def_value = buf->ReadDWord();
07337 }
07338 _cur.grfconfig->has_param_defaults = true;
07339 return true;
07340 }
07341
07342 typedef bool (*DataHandler)(size_t, ByteReader *);
07343 typedef bool (*TextHandler)(byte, const char *str);
07344 typedef bool (*BranchHandler)(ByteReader *);
07345
07353 struct AllowedSubtags {
07355 AllowedSubtags() :
07356 id(0),
07357 type(0)
07358 {}
07359
07365 AllowedSubtags(uint32 id, DataHandler handler) :
07366 id(id),
07367 type('B')
07368 {
07369 this->handler.data = handler;
07370 }
07371
07377 AllowedSubtags(uint32 id, TextHandler handler) :
07378 id(id),
07379 type('T')
07380 {
07381 this->handler.text = handler;
07382 }
07383
07389 AllowedSubtags(uint32 id, BranchHandler handler) :
07390 id(id),
07391 type('C')
07392 {
07393 this->handler.call_handler = true;
07394 this->handler.u.branch = handler;
07395 }
07396
07402 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
07403 id(id),
07404 type('C')
07405 {
07406 this->handler.call_handler = false;
07407 this->handler.u.subtags = subtags;
07408 }
07409
07410 uint32 id;
07411 byte type;
07412 union {
07413 DataHandler data;
07414 TextHandler text;
07415 struct {
07416 union {
07417 BranchHandler branch;
07418 AllowedSubtags *subtags;
07419 } u;
07420 bool call_handler;
07421 };
07422 } handler;
07423 };
07424
07425 static bool SkipUnknownInfo(ByteReader *buf, byte type);
07426 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
07427
07434 static bool ChangeGRFParamValueNames(ByteReader *buf)
07435 {
07436 byte type = buf->ReadByte();
07437 while (type != 0) {
07438 uint32 id = buf->ReadDWord();
07439 if (type != 'T' || id > _cur_parameter->max_value) {
07440 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
07441 if (!SkipUnknownInfo(buf, type)) return false;
07442 type = buf->ReadByte();
07443 continue;
07444 }
07445
07446 byte langid = buf->ReadByte();
07447 const char *name_string = buf->ReadString();
07448
07449 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
07450 if (val_name != _cur_parameter->value_names.End()) {
07451 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
07452 } else {
07453 GRFText *list = NULL;
07454 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
07455 _cur_parameter->value_names.Insert(id, list);
07456 }
07457
07458 type = buf->ReadByte();
07459 }
07460 return true;
07461 }
07462
07464 AllowedSubtags _tags_parameters[] = {
07465 AllowedSubtags('NAME', ChangeGRFParamName),
07466 AllowedSubtags('DESC', ChangeGRFParamDescription),
07467 AllowedSubtags('TYPE', ChangeGRFParamType),
07468 AllowedSubtags('LIMI', ChangeGRFParamLimits),
07469 AllowedSubtags('MASK', ChangeGRFParamMask),
07470 AllowedSubtags('VALU', ChangeGRFParamValueNames),
07471 AllowedSubtags('DFLT', ChangeGRFParamDefault),
07472 AllowedSubtags()
07473 };
07474
07481 static bool HandleParameterInfo(ByteReader *buf)
07482 {
07483 byte type = buf->ReadByte();
07484 while (type != 0) {
07485 uint32 id = buf->ReadDWord();
07486 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
07487 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
07488 if (!SkipUnknownInfo(buf, type)) return false;
07489 type = buf->ReadByte();
07490 continue;
07491 }
07492
07493 if (id >= _cur.grfconfig->param_info.Length()) {
07494 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
07495 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
07496 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
07497 }
07498 if (_cur.grfconfig->param_info[id] == NULL) {
07499 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
07500 }
07501 _cur_parameter = _cur.grfconfig->param_info[id];
07502
07503 if (!HandleNodes(buf, _tags_parameters)) return false;
07504 type = buf->ReadByte();
07505 }
07506 return true;
07507 }
07508
07510 AllowedSubtags _tags_info[] = {
07511 AllowedSubtags('NAME', ChangeGRFName),
07512 AllowedSubtags('DESC', ChangeGRFDescription),
07513 AllowedSubtags('URL_', ChangeGRFURL),
07514 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
07515 AllowedSubtags('PALS', ChangeGRFPalette),
07516 AllowedSubtags('BLTR', ChangeGRFBlitter),
07517 AllowedSubtags('VRSN', ChangeGRFVersion),
07518 AllowedSubtags('MINV', ChangeGRFMinVersion),
07519 AllowedSubtags('PARA', HandleParameterInfo),
07520 AllowedSubtags()
07521 };
07522
07524 AllowedSubtags _tags_root[] = {
07525 AllowedSubtags('INFO', _tags_info),
07526 AllowedSubtags()
07527 };
07528
07529
07536 static bool SkipUnknownInfo(ByteReader *buf, byte type)
07537 {
07538
07539 switch (type) {
07540 case 'C': {
07541 byte new_type = buf->ReadByte();
07542 while (new_type != 0) {
07543 buf->ReadDWord();
07544 if (!SkipUnknownInfo(buf, new_type)) return false;
07545 new_type = buf->ReadByte();
07546 }
07547 break;
07548 }
07549
07550 case 'T':
07551 buf->ReadByte();
07552 buf->ReadString();
07553 break;
07554
07555 case 'B': {
07556 uint16 size = buf->ReadWord();
07557 buf->Skip(size);
07558 break;
07559 }
07560
07561 default:
07562 return false;
07563 }
07564
07565 return true;
07566 }
07567
07576 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
07577 {
07578 uint i = 0;
07579 AllowedSubtags *tag;
07580 while ((tag = &subtags[i++])->type != 0) {
07581 if (tag->id != BSWAP32(id) || tag->type != type) continue;
07582 switch (type) {
07583 default: NOT_REACHED();
07584
07585 case 'T': {
07586 byte langid = buf->ReadByte();
07587 return tag->handler.text(langid, buf->ReadString());
07588 }
07589
07590 case 'B': {
07591 size_t len = buf->ReadWord();
07592 if (buf->Remaining() < len) return false;
07593 return tag->handler.data(len, buf);
07594 }
07595
07596 case 'C': {
07597 if (tag->handler.call_handler) {
07598 return tag->handler.u.branch(buf);
07599 }
07600 return HandleNodes(buf, tag->handler.u.subtags);
07601 }
07602 }
07603 }
07604 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
07605 return SkipUnknownInfo(buf, type);
07606 }
07607
07614 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
07615 {
07616 byte type = buf->ReadByte();
07617 while (type != 0) {
07618 uint32 id = buf->ReadDWord();
07619 if (!HandleNode(type, id, buf, subtags)) return false;
07620 type = buf->ReadByte();
07621 }
07622 return true;
07623 }
07624
07629 static void StaticGRFInfo(ByteReader *buf)
07630 {
07631
07632 HandleNodes(buf, _tags_root);
07633 }
07634
07640 static void GRFUnsafe(ByteReader *buf)
07641 {
07642 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
07643
07644
07645 _cur.skip_sprites = -1;
07646 }
07647
07648
07650 static void InitializeGRFSpecial()
07651 {
07652 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
07653 | (1 << 0x0D)
07654 | (1 << 0x0E)
07655 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
07656 | (0 << 0x10)
07657 | (1 << 0x12)
07658 | (1 << 0x13)
07659 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
07660 | (1 << 0x1B)
07661 | (1 << 0x1D)
07662 | (1 << 0x1E);
07663
07664 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
07665 | (1 << 0x08)
07666 | (1 << 0x09)
07667 | (0 << 0x0B)
07668 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
07669 | (1 << 0x12)
07670 | (1 << 0x13)
07671 | (1 << 0x14)
07672 | (1 << 0x16)
07673 | (1 << 0x17)
07674 | (1 << 0x18)
07675 | (1 << 0x19)
07676 | (1 << 0x1A)
07677 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B)
07678 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07679
07680 _ttdpatch_flags[2] = (1 << 0x01)
07681 | (1 << 0x03)
07682 | (1 << 0x0A)
07683 | (0 << 0x0B)
07684 | (0 << 0x0C)
07685 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07686 | (1 << 0x0E)
07687 | (1 << 0x0F)
07688 | (0 << 0x10)
07689 | (0 << 0x11)
07690 | (1 << 0x12)
07691 | (1 << 0x13)
07692 | (1 << 0x14)
07693 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07694 | (1 << 0x16)
07695 | (1 << 0x17)
07696 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07697 | (1 << 0x19)
07698 | (1 << 0x1A)
07699 | (1 << 0x1B)
07700 | (1 << 0x1C)
07701 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07702 | (1 << 0x1E)
07703 | (0 << 0x1F);
07704
07705 _ttdpatch_flags[3] = (0 << 0x00)
07706 | (1 << 0x01)
07707 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07708 | (1 << 0x03)
07709 | (0 << 0x04)
07710 | (1 << 0x05)
07711 | (1 << 0x06)
07712 | (1 << 0x07)
07713 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07714 | (0 << 0x09)
07715 | (0 << 0x0A)
07716 | (1 << 0x0B)
07717 | (1 << 0x0C)
07718 | (1 << 0x0D)
07719 | (1 << 0x0E)
07720 | (1 << 0x0F)
07721 | (1 << 0x10)
07722 | (1 << 0x11)
07723 | (1 << 0x12)
07724 | (0 << 0x13)
07725 | (1 << 0x14)
07726 | (0 << 0x15)
07727 | (1 << 0x16)
07728 | (1 << 0x17)
07729 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07730 | (1 << 0x1E)
07731 | (1 << 0x1F);
07732 }
07733
07735 static void ResetCustomStations()
07736 {
07737 const GRFFile * const *end = _grf_files.End();
07738 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07739 StationSpec **&stations = (*file)->stations;
07740 if (stations == NULL) continue;
07741 for (uint i = 0; i < MAX_STATIONS; i++) {
07742 if (stations[i] == NULL) continue;
07743 StationSpec *statspec = stations[i];
07744
07745 delete[] statspec->renderdata;
07746
07747
07748 if (!statspec->copied_layouts) {
07749 for (uint l = 0; l < statspec->lengths; l++) {
07750 for (uint p = 0; p < statspec->platforms[l]; p++) {
07751 free(statspec->layouts[l][p]);
07752 }
07753 free(statspec->layouts[l]);
07754 }
07755 free(statspec->layouts);
07756 free(statspec->platforms);
07757 }
07758
07759
07760 free(statspec);
07761 }
07762
07763
07764 free(stations);
07765 stations = NULL;
07766 }
07767 }
07768
07770 static void ResetCustomHouses()
07771 {
07772 const GRFFile * const *end = _grf_files.End();
07773 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07774 HouseSpec **&housespec = (*file)->housespec;
07775 if (housespec == NULL) continue;
07776 for (uint i = 0; i < HOUSE_MAX; i++) {
07777 free(housespec[i]);
07778 }
07779
07780 free(housespec);
07781 housespec = NULL;
07782 }
07783 }
07784
07786 static void ResetCustomAirports()
07787 {
07788 const GRFFile * const *end = _grf_files.End();
07789 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07790 AirportSpec **aslist = (*file)->airportspec;
07791 if (aslist != NULL) {
07792 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07793 AirportSpec *as = aslist[i];
07794
07795 if (as != NULL) {
07796
07797 for (int j = 0; j < as->num_table; j++) {
07798
07799 free(as->table[j]);
07800 }
07801 free(as->table);
07802 free(as->depot_table);
07803
07804 free(as);
07805 }
07806 }
07807 free(aslist);
07808 (*file)->airportspec = NULL;
07809 }
07810
07811 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07812 if (airporttilespec != NULL) {
07813 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07814 free(airporttilespec[i]);
07815 }
07816 free(airporttilespec);
07817 airporttilespec = NULL;
07818 }
07819 }
07820 }
07821
07823 static void ResetCustomIndustries()
07824 {
07825 const GRFFile * const *end = _grf_files.End();
07826 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07827 IndustrySpec **&industryspec = (*file)->industryspec;
07828 IndustryTileSpec **&indtspec = (*file)->indtspec;
07829
07830
07831
07832 if (industryspec != NULL) {
07833 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07834 IndustrySpec *ind = industryspec[i];
07835 if (ind == NULL) continue;
07836
07837
07838 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07839 free(ind->random_sounds);
07840 }
07841
07842
07843 CleanIndustryTileTable(ind);
07844
07845 free(ind);
07846 }
07847
07848 free(industryspec);
07849 industryspec = NULL;
07850 }
07851
07852 if (indtspec == NULL) continue;
07853 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07854 free(indtspec[i]);
07855 }
07856
07857 free(indtspec);
07858 indtspec = NULL;
07859 }
07860 }
07861
07863 static void ResetCustomObjects()
07864 {
07865 const GRFFile * const *end = _grf_files.End();
07866 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07867 ObjectSpec **&objectspec = (*file)->objectspec;
07868 if (objectspec == NULL) continue;
07869 for (uint i = 0; i < NUM_OBJECTS; i++) {
07870 free(objectspec[i]);
07871 }
07872
07873 free(objectspec);
07874 objectspec = NULL;
07875 }
07876 }
07877
07879 static void ResetNewGRF()
07880 {
07881 const GRFFile * const *end = _grf_files.End();
07882 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07883 delete *file;
07884 }
07885
07886 _grf_files.Clear();
07887 _cur.grffile = NULL;
07888 }
07889
07891 static void ResetNewGRFErrors()
07892 {
07893 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07894 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07895 delete c->error;
07896 c->error = NULL;
07897 }
07898 }
07899 }
07900
07905 void ResetNewGRFData()
07906 {
07907 CleanUpStrings();
07908 CleanUpGRFTownNames();
07909
07910
07911 SetupEngines();
07912
07913
07914 ResetBridges();
07915
07916
07917 ResetRailTypes();
07918
07919
07920 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07921
07922
07923 Engine *e;
07924 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07925 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07926 }
07927
07928
07929 memset(&_grm_engines, 0, sizeof(_grm_engines));
07930 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
07931
07932
07933 ResetGenericCallbacks();
07934
07935
07936 ResetPriceBaseMultipliers();
07937
07938
07939 ResetCurrencies();
07940
07941
07942 ResetCustomHouses();
07943 ResetHouses();
07944
07945
07946 ResetCustomIndustries();
07947 ResetIndustries();
07948
07949
07950 ObjectClass::Reset();
07951 ResetCustomObjects();
07952 ResetObjects();
07953
07954
07955 StationClass::Reset();
07956 ResetCustomStations();
07957
07958
07959 AirportClass::Reset();
07960 ResetCustomAirports();
07961 AirportSpec::ResetAirports();
07962 AirportTileSpec::ResetAirportTiles();
07963
07964
07965 memset(_water_feature, 0, sizeof(_water_feature));
07966
07967
07968 ClearSnowLine();
07969
07970
07971 ResetNewGRF();
07972
07973
07974 ResetNewGRFErrors();
07975
07976
07977 SetupCargoForClimate(_settings_game.game_creation.landscape);
07978
07979
07980 _misc_grf_features = 0;
07981
07982 _loaded_newgrf_features.has_2CC = false;
07983 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07984 _loaded_newgrf_features.has_newhouses = false;
07985 _loaded_newgrf_features.has_newindustries = false;
07986 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07987
07988
07989 _grf_id_overrides.clear();
07990
07991 InitializeSoundPool();
07992 _spritegroup_pool.CleanPool();
07993 }
07994
07998 void ResetPersistentNewGRFData()
07999 {
08000
08001 _engine_mngr.ResetToDefaultMapping();
08002 _house_mngr.ResetMapping();
08003 _industry_mngr.ResetMapping();
08004 _industile_mngr.ResetMapping();
08005 _airport_mngr.ResetMapping();
08006 _airporttile_mngr.ResetMapping();
08007 }
08008
08013 static void BuildCargoTranslationMap()
08014 {
08015 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
08016
08017 for (CargoID c = 0; c < NUM_CARGO; c++) {
08018 const CargoSpec *cs = CargoSpec::Get(c);
08019 if (!cs->IsValid()) continue;
08020
08021 if (_cur.grffile->cargo_list.Length() == 0) {
08022
08023 _cur.grffile->cargo_map[c] = cs->bitnum;
08024 } else {
08025
08026 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
08027 if (index >= 0) _cur.grffile->cargo_map[c] = index;
08028 }
08029 }
08030 }
08031
08036 static void InitNewGRFFile(const GRFConfig *config)
08037 {
08038 GRFFile *newfile = GetFileByFilename(config->filename);
08039 if (newfile != NULL) {
08040
08041 _cur.grffile = newfile;
08042 return;
08043 }
08044
08045 newfile = new GRFFile(config);
08046 *_grf_files.Append() = _cur.grffile = newfile;
08047 }
08048
08053 GRFFile::GRFFile(const GRFConfig *config)
08054 {
08055 this->filename = strdup(config->filename);
08056 this->grfid = config->ident.grfid;
08057
08058
08059 this->traininfo_vehicle_pitch = 0;
08060 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
08061
08062
08063 for (Price i = PR_BEGIN; i < PR_END; i++) {
08064 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
08065 }
08066
08067
08068 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
08069 this->railtype_map[0] = RAILTYPE_RAIL;
08070 this->railtype_map[1] = RAILTYPE_ELECTRIC;
08071 this->railtype_map[2] = RAILTYPE_MONO;
08072 this->railtype_map[3] = RAILTYPE_MAGLEV;
08073
08074
08075
08076 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
08077
08078 assert(config->num_params <= lengthof(config->param));
08079 this->param_end = config->num_params;
08080 if (this->param_end > 0) {
08081 MemCpyT(this->param, config->param, this->param_end);
08082 }
08083 }
08084
08085 GRFFile::~GRFFile()
08086 {
08087 free(this->filename);
08088 delete[] this->language_map;
08089 }
08090
08091
08096 static const CargoLabel _default_refitmasks_rail[] = {
08097 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
08098 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
08099 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08100 'PLST', 'FZDR',
08101 0 };
08102
08103 static const CargoLabel _default_refitmasks_road[] = {
08104 0 };
08105
08106 static const CargoLabel _default_refitmasks_ships[] = {
08107 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
08108 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
08109 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08110 'PLST', 'FZDR',
08111 0 };
08112
08113 static const CargoLabel _default_refitmasks_aircraft[] = {
08114 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
08115 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
08116 0 };
08117
08118 static const CargoLabel * const _default_refitmasks[] = {
08119 _default_refitmasks_rail,
08120 _default_refitmasks_road,
08121 _default_refitmasks_ships,
08122 _default_refitmasks_aircraft,
08123 };
08124
08125
08129 static void CalculateRefitMasks()
08130 {
08131 Engine *e;
08132
08133 FOR_ALL_ENGINES(e) {
08134 EngineID engine = e->index;
08135 EngineInfo *ei = &e->info;
08136 bool only_defaultcargo;
08137
08138
08139 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
08140 uint32 mask = 0;
08141 uint32 not_mask = 0;
08142 uint32 xor_mask = ei->refit_mask;
08143
08144
08145
08146 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
08147
08148 if (_gted[engine].cargo_allowed != 0) {
08149
08150 const CargoSpec *cs;
08151 FOR_ALL_CARGOSPECS(cs) {
08152 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
08153 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
08154 }
08155 }
08156
08157 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
08158
08159
08160 ei->refit_mask |= _gted[engine].ctt_include_mask;
08161 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
08162 } else {
08163 uint32 xor_mask = 0;
08164
08165
08166 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
08167 const CargoLabel *cl = _default_refitmasks[e->type];
08168 for (uint i = 0;; i++) {
08169 if (cl[i] == 0) break;
08170
08171 CargoID cargo = GetCargoIDByLabel(cl[i]);
08172 if (cargo == CT_INVALID) continue;
08173
08174 SetBit(xor_mask, cargo);
08175 }
08176 }
08177
08178 ei->refit_mask = xor_mask & _cargo_mask;
08179
08180
08181 only_defaultcargo = (ei->refit_mask == 0);
08182 }
08183
08184
08185
08186 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
08187 ei->cargo_type = CT_INVALID;
08188 }
08189
08190
08191
08192 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
08193
08194 const uint8 *cargo_map_for_first_refittable = NULL;
08195 {
08196 const GRFFile *file = _gted[engine].defaultcargo_grf;
08197 if (file == NULL) file = e->GetGRF();
08198 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
08199 cargo_map_for_first_refittable = file->cargo_map;
08200 }
08201 }
08202
08203 if (cargo_map_for_first_refittable != NULL) {
08204
08205 byte best_local_slot = 0xFF;
08206 CargoID cargo_type;
08207 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
08208 byte local_slot = cargo_map_for_first_refittable[cargo_type];
08209 if (local_slot < best_local_slot) {
08210 best_local_slot = local_slot;
08211 ei->cargo_type = cargo_type;
08212 }
08213 }
08214 }
08215
08216 if (ei->cargo_type == CT_INVALID) {
08217
08218 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
08219 }
08220 }
08221 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
08222
08223
08224 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
08225 ei->refit_mask = 0;
08226 }
08227 }
08228 }
08229
08231 static void FinaliseCanals()
08232 {
08233 for (uint i = 0; i < CF_END; i++) {
08234 if (_water_feature[i].grffile != NULL) {
08235 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
08236 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
08237 }
08238 }
08239 }
08240
08242 static void FinaliseEngineArray()
08243 {
08244 Engine *e;
08245
08246 FOR_ALL_ENGINES(e) {
08247 if (e->GetGRF() == NULL) {
08248 const EngineIDMapping &eid = _engine_mngr[e->index];
08249 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
08250 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
08251 }
08252 }
08253
08254
08255
08256
08257 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
08258 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
08259 }
08260
08261
08262 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
08263 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
08264 SetBit(_loaded_newgrf_features.used_liveries, ls);
08265
08266
08267 if (e->type == VEH_TRAIN) {
08268 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
08269 switch (ls) {
08270 case LS_STEAM:
08271 case LS_DIESEL:
08272 case LS_ELECTRIC:
08273 case LS_MONORAIL:
08274 case LS_MAGLEV:
08275 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
08276 break;
08277
08278 case LS_DMU:
08279 case LS_EMU:
08280 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
08281 break;
08282
08283 default: NOT_REACHED();
08284 }
08285 }
08286 }
08287 }
08288 }
08289
08291 static void FinaliseCargoArray()
08292 {
08293 for (CargoID c = 0; c < NUM_CARGO; c++) {
08294 CargoSpec *cs = CargoSpec::Get(c);
08295 if (!cs->IsValid()) {
08296 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
08297 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
08298 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
08299 }
08300 }
08301 }
08302
08314 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
08315 {
08316 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
08317 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
08318 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
08319 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
08320 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
08321 hs->enabled = false;
08322 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);
08323 return false;
08324 }
08325
08326
08327
08328
08329 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
08330 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
08331 hs->enabled = false;
08332 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);
08333 return false;
08334 }
08335
08336
08337
08338 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
08339 hs->enabled = false;
08340 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);
08341 return false;
08342 }
08343
08344
08345 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
08346 hs->enabled = false;
08347 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);
08348 return false;
08349 }
08350
08351 return true;
08352 }
08353
08360 static void EnsureEarlyHouse(HouseZones bitmask)
08361 {
08362 Year min_year = MAX_YEAR;
08363
08364 for (int i = 0; i < HOUSE_MAX; i++) {
08365 HouseSpec *hs = HouseSpec::Get(i);
08366 if (hs == NULL || !hs->enabled) continue;
08367 if ((hs->building_availability & bitmask) != bitmask) continue;
08368 if (hs->min_year < min_year) min_year = hs->min_year;
08369 }
08370
08371 if (min_year == 0) return;
08372
08373 for (int i = 0; i < HOUSE_MAX; i++) {
08374 HouseSpec *hs = HouseSpec::Get(i);
08375 if (hs == NULL || !hs->enabled) continue;
08376 if ((hs->building_availability & bitmask) != bitmask) continue;
08377 if (hs->min_year == min_year) hs->min_year = 0;
08378 }
08379 }
08380
08387 static void FinaliseHouseArray()
08388 {
08389
08390
08391
08392
08393
08394
08395
08396
08397
08398 const GRFFile * const *end = _grf_files.End();
08399 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08400 HouseSpec **&housespec = (*file)->housespec;
08401 if (housespec == NULL) continue;
08402
08403 for (int i = 0; i < HOUSE_MAX; i++) {
08404 HouseSpec *hs = housespec[i];
08405
08406 if (hs == NULL) continue;
08407
08408 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
08409 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
08410 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
08411
08412 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
08413
08414 _house_mngr.SetEntitySpec(hs);
08415 }
08416 }
08417
08418 for (int i = 0; i < HOUSE_MAX; i++) {
08419 HouseSpec *hs = HouseSpec::Get(i);
08420 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
08421 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
08422 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
08423
08424
08425
08426 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
08427
08428
08429
08430
08431
08432
08433
08434 hs->building_flags = TILE_NO_FLAG;
08435 }
08436 }
08437
08438 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
08439 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
08440 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
08441 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
08442 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
08443 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
08444
08445 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
08446 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
08447 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
08448 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
08449 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
08450 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
08451 }
08452 }
08453
08459 static void FinaliseIndustriesArray()
08460 {
08461 const GRFFile * const *end = _grf_files.End();
08462 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08463 IndustrySpec **&industryspec = (*file)->industryspec;
08464 IndustryTileSpec **&indtspec = (*file)->indtspec;
08465 if (industryspec != NULL) {
08466 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
08467 IndustrySpec *indsp = industryspec[i];
08468
08469 if (indsp != NULL && indsp->enabled) {
08470 StringID strid;
08471
08472
08473
08474 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
08475 if (strid != STR_UNDEFINED) indsp->name = strid;
08476
08477 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
08478 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
08479
08480 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
08481 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
08482
08483 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
08484 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
08485
08486 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
08487 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
08488
08489 if (indsp->station_name != STR_NULL) {
08490
08491
08492 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
08493 if (strid != STR_UNDEFINED) indsp->station_name = strid;
08494 }
08495
08496 _industry_mngr.SetEntitySpec(indsp);
08497 _loaded_newgrf_features.has_newindustries = true;
08498 }
08499 }
08500 }
08501
08502 if (indtspec != NULL) {
08503 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
08504 IndustryTileSpec *indtsp = indtspec[i];
08505 if (indtsp != NULL) {
08506 _industile_mngr.SetEntitySpec(indtsp);
08507 }
08508 }
08509 }
08510 }
08511
08512 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
08513 IndustrySpec *indsp = &_industry_specs[j];
08514 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
08515 for (uint i = 0; i < 3; i++) {
08516 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
08517 }
08518 }
08519 if (!indsp->enabled) {
08520 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
08521 }
08522 }
08523 }
08524
08530 static void FinaliseObjectsArray()
08531 {
08532 const GRFFile * const *end = _grf_files.End();
08533 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08534 ObjectSpec **&objectspec = (*file)->objectspec;
08535 if (objectspec != NULL) {
08536 for (int i = 0; i < NUM_OBJECTS; i++) {
08537 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
08538 _object_mngr.SetEntitySpec(objectspec[i]);
08539 }
08540 }
08541 }
08542 }
08543 }
08544
08550 static void FinaliseAirportsArray()
08551 {
08552 const GRFFile * const *end = _grf_files.End();
08553 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08554 AirportSpec **&airportspec = (*file)->airportspec;
08555 if (airportspec != NULL) {
08556 for (int i = 0; i < NUM_AIRPORTS; i++) {
08557 if (airportspec[i] != NULL && airportspec[i]->enabled) {
08558 _airport_mngr.SetEntitySpec(airportspec[i]);
08559 }
08560 }
08561 }
08562
08563 AirportTileSpec **&airporttilespec = (*file)->airtspec;
08564 if (airporttilespec != NULL) {
08565 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
08566 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
08567 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
08568 }
08569 }
08570 }
08571 }
08572 }
08573
08574
08575
08576
08577
08578
08579
08580 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
08581 {
08582
08583
08584
08585
08586
08587
08588
08589
08590
08591
08592
08593
08594 static const SpecialSpriteHandler handlers[][GLS_END] = {
08595 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
08596 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
08597 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
08598 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
08599 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
08600 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
08601 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
08602 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
08603 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
08604 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
08605 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
08606 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
08607 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
08608 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
08609 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
08610 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
08611 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
08612 { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
08613 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
08614 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
08615 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
08616 };
08617
08618 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
08619
08620 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
08621 if (it == _grf_line_to_action6_sprite_override.end()) {
08622
08623
08624 FioReadBlock(buf, num);
08625 } else {
08626
08627 buf = _grf_line_to_action6_sprite_override[location];
08628 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
08629
08630
08631 FioSeekTo(num, SEEK_CUR);
08632 }
08633
08634 ByteReader br(buf, buf + num);
08635 ByteReader *bufp = &br;
08636
08637 try {
08638 byte action = bufp->ReadByte();
08639
08640 if (action == 0xFF) {
08641 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
08642 } else if (action == 0xFE) {
08643 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
08644 } else if (action >= lengthof(handlers)) {
08645 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
08646 } else if (handlers[action][stage] == NULL) {
08647 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
08648 } else {
08649 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
08650 handlers[action][stage](bufp);
08651 }
08652 } catch (...) {
08653 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
08654 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
08655 }
08656 }
08657
08658
08660 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
08661
08666 byte GetGRFContainerVersion()
08667 {
08668 size_t pos = FioGetPos();
08669
08670 if (FioReadWord() == 0) {
08671
08672
08673 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
08674 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0;
08675 }
08676
08677 return 2;
08678 }
08679
08680
08681 FioSeekTo(pos, SEEK_SET);
08682 return 1;
08683 }
08684
08692 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
08693 {
08694 const char *filename = config->filename;
08695
08696
08697
08698
08699
08700
08701
08702
08703
08704
08705 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
08706 _cur.grffile = GetFileByFilename(filename);
08707 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
08708 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
08709 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
08710 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
08711 }
08712
08713 if (file_index > LAST_GRF_SLOT) {
08714 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
08715 config->status = GCS_DISABLED;
08716 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
08717 return;
08718 }
08719
08720 FioOpenFile(file_index, filename, subdir);
08721 _cur.file_index = file_index;
08722 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
08723
08724 _cur.grfconfig = config;
08725
08726 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
08727
08728 _cur.grf_container_ver = GetGRFContainerVersion();
08729 if (_cur.grf_container_ver == 0) {
08730 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08731 return;
08732 }
08733
08734 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
08735
08736
08737 ReadGRFSpriteOffsets(_cur.grf_container_ver);
08738 } else {
08739
08740 if (_cur.grf_container_ver >= 2) FioReadDword();
08741 }
08742
08743 if (_cur.grf_container_ver >= 2) {
08744
08745 byte compression = FioReadByte();
08746 if (compression != 0) {
08747 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
08748 return;
08749 }
08750 }
08751
08752
08753
08754
08755 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
08756 if (num == 4 && FioReadByte() == 0xFF) {
08757 FioReadDword();
08758 } else {
08759 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08760 return;
08761 }
08762
08763 _cur.ClearDataForNextFile();
08764
08765 ReusableBuffer<byte> buf;
08766
08767 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
08768 byte type = FioReadByte();
08769 _cur.nfo_line++;
08770
08771 if (type == 0xFF) {
08772 if (_cur.skip_sprites == 0) {
08773 DecodeSpecialSprite(buf.Allocate(num), num, stage);
08774
08775
08776 if (_cur.skip_sprites == -1) break;
08777
08778 continue;
08779 } else {
08780 FioSkipBytes(num);
08781 }
08782 } else {
08783 if (_cur.skip_sprites == 0) {
08784 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08785 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08786 break;
08787 }
08788
08789 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
08790
08791 FioSkipBytes(num);
08792 } else {
08793 FioSkipBytes(7);
08794 SkipSpriteData(type, num - 8);
08795 }
08796 }
08797
08798 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
08799 }
08800 }
08801
08809 static void ActivateOldShore()
08810 {
08811
08812
08813 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08814
08815 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08816 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08817 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08818 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08819 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08820 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08821 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08822 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08823 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08824 }
08825
08826 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08827 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08828 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08829 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08830 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08831 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08832 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08833 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08834 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08835
08836
08837
08838 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08839 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08840 }
08841 }
08842
08846 static void FinalisePriceBaseMultipliers()
08847 {
08848 extern const PriceBaseSpec _price_base_specs[];
08850 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08851
08852
08853 int num_grfs = _grf_files.Length();
08854 int *grf_overrides = AllocaM(int, num_grfs);
08855 for (int i = 0; i < num_grfs; i++) {
08856 grf_overrides[i] = -1;
08857
08858 GRFFile *source = _grf_files[i];
08859 uint32 override = _grf_id_overrides[source->grfid];
08860 if (override == 0) continue;
08861
08862 GRFFile *dest = GetFileByGRFID(override);
08863 if (dest == NULL) continue;
08864
08865 grf_overrides[i] = _grf_files.FindIndex(dest);
08866 assert(grf_overrides[i] >= 0);
08867 }
08868
08869
08870 for (int i = 0; i < num_grfs; i++) {
08871 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08872 GRFFile *source = _grf_files[i];
08873 GRFFile *dest = _grf_files[grf_overrides[i]];
08874
08875 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08876 source->grf_features |= features;
08877 dest->grf_features |= features;
08878
08879 for (Price p = PR_BEGIN; p < PR_END; p++) {
08880
08881 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08882 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08883 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08884 }
08885 }
08886
08887
08888 for (int i = num_grfs - 1; i >= 0; i--) {
08889 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08890 GRFFile *source = _grf_files[i];
08891 GRFFile *dest = _grf_files[grf_overrides[i]];
08892
08893 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08894 source->grf_features |= features;
08895 dest->grf_features |= features;
08896
08897 for (Price p = PR_BEGIN; p < PR_END; p++) {
08898
08899 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08900 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08901 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08902 }
08903 }
08904
08905
08906 for (int i = 0; i < num_grfs; i++) {
08907 if (grf_overrides[i] < 0) continue;
08908 GRFFile *source = _grf_files[i];
08909 GRFFile *dest = _grf_files[grf_overrides[i]];
08910
08911 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08912 source->grf_features |= features;
08913 dest->grf_features |= features;
08914
08915 for (Price p = PR_BEGIN; p < PR_END; p++) {
08916 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08917 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08918 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08919 }
08920 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08921 }
08922 }
08923
08924
08925 const GRFFile * const *end = _grf_files.End();
08926 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08927 if ((*file)->grf_version >= 8) continue;
08928 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08929 for (Price p = PR_BEGIN; p < PR_END; p++) {
08930 Price fallback_price = _price_base_specs[p].fallback_price;
08931 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08932
08933
08934 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08935 }
08936 }
08937 }
08938
08939
08940 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08941 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08942 for (Price p = PR_BEGIN; p < PR_END; p++) {
08943 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08944
08945 price_base_multipliers[p] = 0;
08946 } else {
08947 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08948
08949
08950 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08951 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08952 price_base_multipliers[p] = 0;
08953 } else {
08954 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08955 }
08956 }
08957 }
08958 }
08959 }
08960
08961 void InitDepotWindowBlockSizes();
08962
08963 extern void InitGRFTownGeneratorNames();
08964
08966 static void AfterLoadGRFs()
08967 {
08968 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08969 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08970 }
08971 _string_to_grf_mapping.clear();
08972
08973
08974 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08975 free((*it).second);
08976 }
08977 _grf_line_to_action6_sprite_override.clear();
08978
08979
08980 FinaliseCargoArray();
08981
08982
08983 CalculateRefitMasks();
08984
08985
08986 FinaliseEngineArray();
08987
08988
08989 FinaliseCanals();
08990
08991
08992 InitDepotWindowBlockSizes();
08993
08994
08995 FinaliseHouseArray();
08996
08997
08998 FinaliseIndustriesArray();
08999
09000
09001 FinaliseObjectsArray();
09002
09003 InitializeSortedCargoSpecs();
09004
09005
09006 SortIndustryTypes();
09007
09008
09009 BuildIndustriesLegend();
09010
09011
09012 BuildLinkStatsLegend();
09013
09014
09015 FinaliseAirportsArray();
09016 BindAirportSpecs();
09017
09018
09019 InitGRFTownGeneratorNames();
09020
09021
09022 CommitVehicleListOrderChanges();
09023
09024
09025 ActivateOldShore();
09026
09027
09028 InitRailTypes();
09029
09030 Engine *e;
09031 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
09032 if (_gted[e->index].rv_max_speed != 0) {
09033
09034 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
09035 }
09036 }
09037
09038 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
09039 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
09040 if (railtype == INVALID_RAILTYPE) {
09041
09042 e->info.climates = 0;
09043 } else {
09044 e->u.rail.railtype = railtype;
09045 }
09046 }
09047
09048 SetYearEngineAgingStops();
09049
09050 FinalisePriceBaseMultipliers();
09051
09052
09053 free(_gted);
09054 _grm_sprites.clear();
09055 }
09056
09062 void LoadNewGRF(uint load_index, uint file_index)
09063 {
09064
09065
09066
09067
09068 Date date = _date;
09069 Year year = _cur_year;
09070 DateFract date_fract = _date_fract;
09071 uint16 tick_counter = _tick_counter;
09072 byte display_opt = _display_opt;
09073
09074 if (_networking) {
09075 _cur_year = _settings_game.game_creation.starting_year;
09076 _date = ConvertYMDToDate(_cur_year, 0, 1);
09077 _date_fract = 0;
09078 _tick_counter = 0;
09079 _display_opt = 0;
09080 }
09081
09082 InitializeGRFSpecial();
09083
09084 ResetNewGRFData();
09085
09086
09087
09088
09089
09090
09091
09092
09093 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09094 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
09095 }
09096
09097 _cur.spriteid = load_index;
09098
09099
09100
09101
09102 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
09103
09104
09105 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09106 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
09107 }
09108
09109 if (stage == GLS_RESERVE) {
09110 static const uint32 overrides[][2] = {
09111 { 0x44442202, 0x44440111 },
09112 { 0x6D620402, 0x6D620401 },
09113 { 0x4D656f20, 0x4D656F17 },
09114 };
09115 for (size_t i = 0; i < lengthof(overrides); i++) {
09116 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
09117 }
09118 }
09119
09120 uint slot = file_index;
09121
09122 _cur.stage = stage;
09123 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09124 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
09125 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
09126
09127 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
09128 if (!FioCheckFileExists(c->filename, subdir)) {
09129 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
09130 c->status = GCS_NOT_FOUND;
09131 continue;
09132 }
09133
09134 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
09135 LoadNewGRFFile(c, slot++, stage, subdir);
09136 if (stage == GLS_RESERVE) {
09137 SetBit(c->flags, GCF_RESERVED);
09138 } else if (stage == GLS_ACTIVATION) {
09139 ClrBit(c->flags, GCF_RESERVED);
09140 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
09141 ClearTemporaryNewGRFData(_cur.grffile);
09142 BuildCargoTranslationMap();
09143 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
09144 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
09145
09146 ClearTemporaryNewGRFData(_cur.grffile);
09147 }
09148 }
09149 }
09150
09151
09152 _cur.ClearDataForNextFile();
09153
09154
09155 AfterLoadGRFs();
09156
09157
09158 _cur_year = year;
09159 _date = date;
09160 _date_fract = date_fract;
09161 _tick_counter = tick_counter;
09162 _display_opt = display_opt;
09163 }