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