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