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