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));
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 default:
03956 ret = CIR_UNKNOWN;
03957 break;
03958 }
03959 }
03960
03961 return ret;
03962 }
03963
03964 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
03965 {
03966 ChangeInfoResult ret = CIR_SUCCESS;
03967
03968 if (id + numinfo > RAILTYPE_END) {
03969 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03970 return CIR_INVALID_ID;
03971 }
03972
03973 for (int i = 0; i < numinfo; i++) {
03974 switch (prop) {
03975 case 0x08:
03976 {
03977 RailTypeLabel rtl = buf->ReadDWord();
03978 rtl = BSWAP32(rtl);
03979
03980 RailType rt = GetRailTypeByLabel(rtl);
03981 if (rt == INVALID_RAILTYPE) {
03982
03983 rt = AllocateRailType(rtl);
03984 }
03985
03986 _cur.grffile->railtype_map[id + i] = rt;
03987 break;
03988 }
03989
03990 case 0x09:
03991 case 0x0A:
03992 case 0x0B:
03993 case 0x0C:
03994 case 0x0D:
03995 case 0x13:
03996 case 0x14:
03997 case 0x1B:
03998 case 0x1C:
03999 buf->ReadWord();
04000 break;
04001
04002 case 0x0E:
04003 case 0x0F:
04004 case 0x18:
04005 case 0x19:
04006 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
04007 break;
04008
04009 case 0x10:
04010 case 0x11:
04011 case 0x12:
04012 case 0x15:
04013 case 0x16:
04014 case 0x1A:
04015 buf->ReadByte();
04016 break;
04017
04018 case 0x17:
04019 buf->ReadDWord();
04020 break;
04021
04022 default:
04023 ret = CIR_UNKNOWN;
04024 break;
04025 }
04026 }
04027
04028 return ret;
04029 }
04030
04031 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
04032 {
04033 ChangeInfoResult ret = CIR_SUCCESS;
04034
04035 if (airtid + numinfo > NUM_AIRPORTTILES) {
04036 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
04037 return CIR_INVALID_ID;
04038 }
04039
04040
04041 if (_cur.grffile->airtspec == NULL) {
04042 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
04043 }
04044
04045 for (int i = 0; i < numinfo; i++) {
04046 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
04047
04048 if (prop != 0x08 && tsp == NULL) {
04049 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
04050 return CIR_INVALID_ID;
04051 }
04052
04053 switch (prop) {
04054 case 0x08: {
04055 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
04056 byte subs_id = buf->ReadByte();
04057
04058 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
04059
04060 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
04061 continue;
04062 }
04063
04064
04065 if (*tilespec == NULL) {
04066 *tilespec = CallocT<AirportTileSpec>(1);
04067 tsp = *tilespec;
04068
04069 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
04070 tsp->enabled = true;
04071
04072 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
04073
04074 tsp->grf_prop.local_id = airtid + i;
04075 tsp->grf_prop.subst_id = subs_id;
04076 tsp->grf_prop.grffile = _cur.grffile;
04077 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id);
04078 }
04079 break;
04080 }
04081
04082 case 0x09: {
04083 byte override = buf->ReadByte();
04084
04085
04086 if (override >= NEW_AIRPORTTILE_OFFSET) {
04087 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
04088 continue;
04089 }
04090
04091 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
04092 break;
04093 }
04094
04095 case 0x0E:
04096 tsp->callback_mask = buf->ReadByte();
04097 break;
04098
04099 case 0x0F:
04100 tsp->animation.frames = buf->ReadByte();
04101 tsp->animation.status = buf->ReadByte();
04102 break;
04103
04104 case 0x10:
04105 tsp->animation.speed = buf->ReadByte();
04106 break;
04107
04108 case 0x11:
04109 tsp->animation.triggers = buf->ReadByte();
04110 break;
04111
04112 default:
04113 ret = CIR_UNKNOWN;
04114 break;
04115 }
04116 }
04117
04118 return ret;
04119 }
04120
04121 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
04122 {
04123 switch (cir) {
04124 default: NOT_REACHED();
04125
04126 case CIR_DISABLED:
04127
04128 return true;
04129
04130 case CIR_SUCCESS:
04131 return false;
04132
04133 case CIR_UNHANDLED:
04134 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
04135 return false;
04136
04137 case CIR_UNKNOWN:
04138 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
04139
04140
04141 case CIR_INVALID_ID:
04142
04143 DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
04144 return true;
04145 }
04146 }
04147
04148
04149 static void FeatureChangeInfo(ByteReader *buf)
04150 {
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162 static const VCI_Handler handler[] = {
04163 RailVehicleChangeInfo,
04164 RoadVehicleChangeInfo,
04165 ShipVehicleChangeInfo,
04166 AircraftVehicleChangeInfo,
04167 StationChangeInfo,
04168 CanalChangeInfo,
04169 BridgeChangeInfo,
04170 TownHouseChangeInfo,
04171 GlobalVarChangeInfo,
04172 IndustrytilesChangeInfo,
04173 IndustriesChangeInfo,
04174 NULL,
04175 SoundEffectChangeInfo,
04176 AirportChangeInfo,
04177 NULL,
04178 ObjectChangeInfo,
04179 RailTypeChangeInfo,
04180 AirportTilesChangeInfo,
04181 };
04182
04183 uint8 feature = buf->ReadByte();
04184 uint8 numprops = buf->ReadByte();
04185 uint numinfo = buf->ReadByte();
04186 uint engine = buf->ReadExtendedByte();
04187
04188 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
04189 feature, numprops, engine, numinfo);
04190
04191 if (feature >= lengthof(handler) || handler[feature] == NULL) {
04192 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
04193 return;
04194 }
04195
04196
04197 SetBit(_cur.grffile->grf_features, feature);
04198
04199 while (numprops-- && buf->HasData()) {
04200 uint8 prop = buf->ReadByte();
04201
04202 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
04203 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
04204 }
04205 }
04206
04207
04208 static void SafeChangeInfo(ByteReader *buf)
04209 {
04210 uint8 feature = buf->ReadByte();
04211 uint8 numprops = buf->ReadByte();
04212 uint numinfo = buf->ReadByte();
04213 buf->ReadExtendedByte();
04214
04215 if (feature == GSF_BRIDGES && numprops == 1) {
04216 uint8 prop = buf->ReadByte();
04217
04218
04219 if (prop == 0x0D) return;
04220 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
04221 uint8 prop = buf->ReadByte();
04222
04223 if (prop == 0x11) {
04224 bool is_safe = true;
04225 for (uint i = 0; i < numinfo; i++) {
04226 uint32 s = buf->ReadDWord();
04227 buf->ReadDWord();
04228 const GRFConfig *grfconfig = GetGRFConfig(s);
04229 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
04230 is_safe = false;
04231 break;
04232 }
04233 }
04234 if (is_safe) return;
04235 }
04236 }
04237
04238 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
04239
04240
04241 _cur.skip_sprites = -1;
04242 }
04243
04244
04245 static void ReserveChangeInfo(ByteReader *buf)
04246 {
04247 uint8 feature = buf->ReadByte();
04248
04249 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
04250
04251 uint8 numprops = buf->ReadByte();
04252 uint8 numinfo = buf->ReadByte();
04253 uint8 index = buf->ReadExtendedByte();
04254
04255 while (numprops-- && buf->HasData()) {
04256 uint8 prop = buf->ReadByte();
04257 ChangeInfoResult cir = CIR_SUCCESS;
04258
04259 switch (feature) {
04260 default: NOT_REACHED();
04261 case GSF_CARGOES:
04262 cir = CargoChangeInfo(index, numinfo, prop, buf);
04263 break;
04264
04265 case GSF_GLOBALVAR:
04266 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
04267 break;
04268
04269 case GSF_RAILTYPES:
04270 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
04271 break;
04272 }
04273
04274 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
04275 }
04276 }
04277
04278
04279 static void NewSpriteSet(ByteReader *buf)
04280 {
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293 uint8 feature = buf->ReadByte();
04294 uint8 num_sets = buf->ReadByte();
04295 uint16 first_set = 0;
04296
04297 if (num_sets == 0 && buf->HasData(2)) {
04298
04299
04300 first_set = buf->ReadExtendedByte();
04301 num_sets = buf->ReadExtendedByte();
04302 }
04303 uint16 num_ents = buf->ReadExtendedByte();
04304
04305 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
04306
04307 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
04308 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
04309 );
04310
04311 for (int i = 0; i < num_sets * num_ents; i++) {
04312 _cur.nfo_line++;
04313 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
04314 }
04315 }
04316
04317
04318 static void SkipAct1(ByteReader *buf)
04319 {
04320 buf->ReadByte();
04321 uint8 num_sets = buf->ReadByte();
04322 uint16 num_ents = buf->ReadExtendedByte();
04323
04324 _cur.skip_sprites = num_sets * num_ents;
04325
04326 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
04327 }
04328
04329
04330
04331 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
04332 {
04333 if (HasBit(groupid, 15)) {
04334 assert(CallbackResultSpriteGroup::CanAllocateItem());
04335 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
04336 }
04337
04338 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04339 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
04340 return NULL;
04341 }
04342
04343 return _cur.spritegroups[groupid];
04344 }
04345
04354 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
04355 {
04356 if (HasBit(spriteid, 15)) {
04357 assert(CallbackResultSpriteGroup::CanAllocateItem());
04358 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
04359 }
04360
04361 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
04362 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
04363 return NULL;
04364 }
04365
04366 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
04367 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
04368
04369
04370 assert(spriteset_start + num_sprites <= _cur.spriteid);
04371
04372 assert(ResultSpriteGroup::CanAllocateItem());
04373 return new ResultSpriteGroup(spriteset_start, num_sprites);
04374 }
04375
04376
04377 static void NewSpriteGroup(ByteReader *buf)
04378 {
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389 SpriteGroup *act_group = NULL;
04390
04391 uint8 feature = buf->ReadByte();
04392 uint8 setid = buf->ReadByte();
04393 uint8 type = buf->ReadByte();
04394
04395
04396
04397
04398
04399 switch (type) {
04400
04401 case 0x81:
04402 case 0x82:
04403 case 0x85:
04404 case 0x86:
04405 case 0x89:
04406 case 0x8A:
04407 {
04408 byte varadjust;
04409 byte varsize;
04410
04411 assert(DeterministicSpriteGroup::CanAllocateItem());
04412 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
04413 act_group = group;
04414 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04415
04416 switch (GB(type, 2, 2)) {
04417 default: NOT_REACHED();
04418 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
04419 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
04420 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
04421 }
04422
04423 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
04424 adjusts.Clear();
04425
04426
04427
04428 do {
04429 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
04430
04431
04432 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
04433 adjust->variable = buf->ReadByte();
04434 if (adjust->variable == 0x7E) {
04435
04436 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
04437 } else {
04438 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
04439 }
04440
04441 varadjust = buf->ReadByte();
04442 adjust->shift_num = GB(varadjust, 0, 5);
04443 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
04444 adjust->and_mask = buf->ReadVarSize(varsize);
04445
04446 if (adjust->type != DSGA_TYPE_NONE) {
04447 adjust->add_val = buf->ReadVarSize(varsize);
04448 adjust->divmod_val = buf->ReadVarSize(varsize);
04449 } else {
04450 adjust->add_val = 0;
04451 adjust->divmod_val = 0;
04452 }
04453
04454
04455 } while (HasBit(varadjust, 5));
04456
04457 group->num_adjusts = adjusts.Length();
04458 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
04459 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
04460
04461 group->num_ranges = buf->ReadByte();
04462 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
04463
04464 for (uint i = 0; i < group->num_ranges; i++) {
04465 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04466 group->ranges[i].low = buf->ReadVarSize(varsize);
04467 group->ranges[i].high = buf->ReadVarSize(varsize);
04468 }
04469
04470 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04471 break;
04472 }
04473
04474
04475 case 0x80:
04476 case 0x83:
04477 case 0x84:
04478 {
04479 assert(RandomizedSpriteGroup::CanAllocateItem());
04480 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
04481 act_group = group;
04482 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04483
04484 if (HasBit(type, 2)) {
04485 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
04486 group->count = buf->ReadByte();
04487 }
04488
04489 uint8 triggers = buf->ReadByte();
04490 group->triggers = GB(triggers, 0, 7);
04491 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
04492 group->lowest_randbit = buf->ReadByte();
04493 group->num_groups = buf->ReadByte();
04494 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
04495
04496 for (uint i = 0; i < group->num_groups; i++) {
04497 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
04498 }
04499
04500 break;
04501 }
04502
04503
04504 default:
04505 {
04506 switch (feature) {
04507 case GSF_TRAINS:
04508 case GSF_ROADVEHICLES:
04509 case GSF_SHIPS:
04510 case GSF_AIRCRAFT:
04511 case GSF_STATIONS:
04512 case GSF_CANALS:
04513 case GSF_CARGOES:
04514 case GSF_AIRPORTS:
04515 case GSF_RAILTYPES:
04516 {
04517 byte num_loaded = type;
04518 byte num_loading = buf->ReadByte();
04519
04520 if (!_cur.HasValidSpriteSets(feature)) {
04521 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
04522 return;
04523 }
04524
04525 assert(RealSpriteGroup::CanAllocateItem());
04526 RealSpriteGroup *group = new RealSpriteGroup();
04527 act_group = group;
04528
04529 group->num_loaded = num_loaded;
04530 group->num_loading = num_loading;
04531 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
04532 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
04533
04534 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
04535 setid, num_loaded, num_loading);
04536
04537 for (uint i = 0; i < num_loaded; i++) {
04538 uint16 spriteid = buf->ReadWord();
04539 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04540 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
04541 }
04542
04543 for (uint i = 0; i < num_loading; i++) {
04544 uint16 spriteid = buf->ReadWord();
04545 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04546 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
04547 }
04548
04549 break;
04550 }
04551
04552 case GSF_HOUSES:
04553 case GSF_AIRPORTTILES:
04554 case GSF_OBJECTS:
04555 case GSF_INDUSTRYTILES: {
04556 byte num_building_sprites = max((uint8)1, type);
04557
04558 assert(TileLayoutSpriteGroup::CanAllocateItem());
04559 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
04560 act_group = group;
04561
04562
04563 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
04564 break;
04565 }
04566
04567 case GSF_INDUSTRIES: {
04568 if (type > 1) {
04569 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
04570 break;
04571 }
04572
04573 assert(IndustryProductionSpriteGroup::CanAllocateItem());
04574 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04575 act_group = group;
04576 group->version = type;
04577 if (type == 0) {
04578 for (uint i = 0; i < 3; i++) {
04579 group->subtract_input[i] = (int16)buf->ReadWord();
04580 }
04581 for (uint i = 0; i < 2; i++) {
04582 group->add_output[i] = buf->ReadWord();
04583 }
04584 group->again = buf->ReadByte();
04585 } else {
04586 for (uint i = 0; i < 3; i++) {
04587 group->subtract_input[i] = buf->ReadByte();
04588 }
04589 for (uint i = 0; i < 2; i++) {
04590 group->add_output[i] = buf->ReadByte();
04591 }
04592 group->again = buf->ReadByte();
04593 }
04594 break;
04595 }
04596
04597
04598 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04599 }
04600 }
04601 }
04602
04603 _cur.spritegroups[setid] = act_group;
04604 }
04605
04606 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04607 {
04608 if (feature == GSF_OBJECTS) {
04609 switch (ctype) {
04610 case 0: return 0;
04611 case 0xFF: return CT_PURCHASE_OBJECT;
04612 default:
04613 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04614 return CT_INVALID;
04615 }
04616 }
04617
04618 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04619 if (ctype == 0xFF) return CT_PURCHASE;
04620
04621 if (_cur.grffile->cargo_max == 0) {
04622
04623 if (ctype >= 32) {
04624 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04625 return CT_INVALID;
04626 }
04627
04628 const CargoSpec *cs;
04629 FOR_ALL_CARGOSPECS(cs) {
04630 if (cs->bitnum == ctype) {
04631 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04632 return cs->Index();
04633 }
04634 }
04635
04636 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04637 return CT_INVALID;
04638 }
04639
04640
04641 if (ctype >= _cur.grffile->cargo_max) {
04642 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_max - 1);
04643 return CT_INVALID;
04644 }
04645
04646
04647 CargoLabel cl = _cur.grffile->cargo_list[ctype];
04648 if (cl == 0) {
04649 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04650 return CT_INVALID;
04651 }
04652
04653 ctype = GetCargoIDByLabel(cl);
04654 if (ctype == CT_INVALID) {
04655 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));
04656 return CT_INVALID;
04657 }
04658
04659 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);
04660 return ctype;
04661 }
04662
04663
04664 static bool IsValidGroupID(uint16 groupid, const char *function)
04665 {
04666 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04667 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
04668 return false;
04669 }
04670
04671 return true;
04672 }
04673
04674 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04675 {
04676 static EngineID *last_engines;
04677 static uint last_engines_count;
04678 bool wagover = false;
04679
04680
04681 if (HasBit(idcount, 7)) {
04682 wagover = true;
04683
04684 idcount = GB(idcount, 0, 7);
04685
04686 if (last_engines_count == 0) {
04687 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04688 return;
04689 }
04690
04691 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04692 last_engines_count, idcount);
04693 } else {
04694 if (last_engines_count != idcount) {
04695 last_engines = ReallocT(last_engines, idcount);
04696 last_engines_count = idcount;
04697 }
04698 }
04699
04700 EngineID *engines = AllocaM(EngineID, idcount);
04701 for (uint i = 0; i < idcount; i++) {
04702 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
04703 if (e == NULL) {
04704
04705
04706
04707 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04708 return;
04709 }
04710
04711 engines[i] = e->index;
04712 if (!wagover) last_engines[i] = engines[i];
04713 }
04714
04715 uint8 cidcount = buf->ReadByte();
04716 for (uint c = 0; c < cidcount; c++) {
04717 uint8 ctype = buf->ReadByte();
04718 uint16 groupid = buf->ReadWord();
04719 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04720
04721 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04722
04723 ctype = TranslateCargo(feature, ctype);
04724 if (ctype == CT_INVALID) continue;
04725
04726 for (uint i = 0; i < idcount; i++) {
04727 EngineID engine = engines[i];
04728
04729 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04730
04731 if (wagover) {
04732 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
04733 } else {
04734 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
04735 }
04736 }
04737 }
04738
04739 uint16 groupid = buf->ReadWord();
04740 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04741
04742 grfmsg(8, "-- Default group id 0x%04X", groupid);
04743
04744 for (uint i = 0; i < idcount; i++) {
04745 EngineID engine = engines[i];
04746
04747 if (wagover) {
04748 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
04749 } else {
04750 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
04751 SetEngineGRF(engine, _cur.grffile);
04752 }
04753 }
04754 }
04755
04756
04757 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04758 {
04759 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04760 for (uint i = 0; i < idcount; i++) {
04761 cfs[i] = (CanalFeature)buf->ReadByte();
04762 }
04763
04764 uint8 cidcount = buf->ReadByte();
04765 buf->Skip(cidcount * 3);
04766
04767 uint16 groupid = buf->ReadWord();
04768 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04769
04770 for (uint i = 0; i < idcount; i++) {
04771 CanalFeature cf = cfs[i];
04772
04773 if (cf >= CF_END) {
04774 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04775 continue;
04776 }
04777
04778 _water_feature[cf].grffile = _cur.grffile;
04779 _water_feature[cf].group = _cur.spritegroups[groupid];
04780 }
04781 }
04782
04783
04784 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04785 {
04786 uint8 *stations = AllocaM(uint8, idcount);
04787 for (uint i = 0; i < idcount; i++) {
04788 stations[i] = buf->ReadByte();
04789 }
04790
04791 uint8 cidcount = buf->ReadByte();
04792 for (uint c = 0; c < cidcount; c++) {
04793 uint8 ctype = buf->ReadByte();
04794 uint16 groupid = buf->ReadWord();
04795 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04796
04797 ctype = TranslateCargo(GSF_STATIONS, ctype);
04798 if (ctype == CT_INVALID) continue;
04799
04800 for (uint i = 0; i < idcount; i++) {
04801 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04802
04803 if (statspec == NULL) {
04804 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04805 continue;
04806 }
04807
04808 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
04809 }
04810 }
04811
04812 uint16 groupid = buf->ReadWord();
04813 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04814
04815 for (uint i = 0; i < idcount; i++) {
04816 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04817
04818 if (statspec == NULL) {
04819 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04820 continue;
04821 }
04822
04823 if (statspec->grf_prop.grffile != NULL) {
04824 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04825 continue;
04826 }
04827
04828 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
04829 statspec->grf_prop.grffile = _cur.grffile;
04830 statspec->grf_prop.local_id = stations[i];
04831 StationClass::Assign(statspec);
04832 }
04833 }
04834
04835
04836 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04837 {
04838 uint8 *houses = AllocaM(uint8, idcount);
04839 for (uint i = 0; i < idcount; i++) {
04840 houses[i] = buf->ReadByte();
04841 }
04842
04843
04844 uint8 cidcount = buf->ReadByte();
04845 buf->Skip(cidcount * 3);
04846
04847 uint16 groupid = buf->ReadWord();
04848 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04849
04850 if (_cur.grffile->housespec == NULL) {
04851 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04852 return;
04853 }
04854
04855 for (uint i = 0; i < idcount; i++) {
04856 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
04857
04858 if (hs == NULL) {
04859 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04860 continue;
04861 }
04862
04863 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04864 }
04865 }
04866
04867 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04868 {
04869 uint8 *industries = AllocaM(uint8, idcount);
04870 for (uint i = 0; i < idcount; i++) {
04871 industries[i] = buf->ReadByte();
04872 }
04873
04874
04875 uint8 cidcount = buf->ReadByte();
04876 buf->Skip(cidcount * 3);
04877
04878 uint16 groupid = buf->ReadWord();
04879 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04880
04881 if (_cur.grffile->industryspec == NULL) {
04882 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04883 return;
04884 }
04885
04886 for (uint i = 0; i < idcount; i++) {
04887 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
04888
04889 if (indsp == NULL) {
04890 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04891 continue;
04892 }
04893
04894 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04895 }
04896 }
04897
04898 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04899 {
04900 uint8 *indtiles = AllocaM(uint8, idcount);
04901 for (uint i = 0; i < idcount; i++) {
04902 indtiles[i] = buf->ReadByte();
04903 }
04904
04905
04906 uint8 cidcount = buf->ReadByte();
04907 buf->Skip(cidcount * 3);
04908
04909 uint16 groupid = buf->ReadWord();
04910 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
04911
04912 if (_cur.grffile->indtspec == NULL) {
04913 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
04914 return;
04915 }
04916
04917 for (uint i = 0; i < idcount; i++) {
04918 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
04919
04920 if (indtsp == NULL) {
04921 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
04922 continue;
04923 }
04924
04925 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04926 }
04927 }
04928
04929 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
04930 {
04931 CargoID *cargoes = AllocaM(CargoID, idcount);
04932 for (uint i = 0; i < idcount; i++) {
04933 cargoes[i] = buf->ReadByte();
04934 }
04935
04936
04937 uint8 cidcount = buf->ReadByte();
04938 buf->Skip(cidcount * 3);
04939
04940 uint16 groupid = buf->ReadWord();
04941 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
04942
04943 for (uint i = 0; i < idcount; i++) {
04944 CargoID cid = cargoes[i];
04945
04946 if (cid >= NUM_CARGO) {
04947 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
04948 continue;
04949 }
04950
04951 CargoSpec *cs = CargoSpec::Get(cid);
04952 cs->grffile = _cur.grffile;
04953 cs->group = _cur.spritegroups[groupid];
04954 }
04955 }
04956
04957 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
04958 {
04959 if (_cur.grffile->objectspec == NULL) {
04960 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
04961 return;
04962 }
04963
04964 uint8 *objects = AllocaM(uint8, idcount);
04965 for (uint i = 0; i < idcount; i++) {
04966 objects[i] = buf->ReadByte();
04967 }
04968
04969 uint8 cidcount = buf->ReadByte();
04970 for (uint c = 0; c < cidcount; c++) {
04971 uint8 ctype = buf->ReadByte();
04972 uint16 groupid = buf->ReadWord();
04973 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
04974
04975 ctype = TranslateCargo(GSF_OBJECTS, ctype);
04976 if (ctype == CT_INVALID) continue;
04977
04978 for (uint i = 0; i < idcount; i++) {
04979 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
04980
04981 if (spec == NULL) {
04982 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04983 continue;
04984 }
04985
04986 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
04987 }
04988 }
04989
04990 uint16 groupid = buf->ReadWord();
04991 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
04992
04993 for (uint i = 0; i < idcount; i++) {
04994 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
04995
04996 if (spec == NULL) {
04997 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04998 continue;
04999 }
05000
05001 if (spec->grf_prop.grffile != NULL) {
05002 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
05003 continue;
05004 }
05005
05006 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05007 spec->grf_prop.grffile = _cur.grffile;
05008 spec->grf_prop.local_id = objects[i];
05009 }
05010 }
05011
05012 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
05013 {
05014 uint8 *railtypes = AllocaM(uint8, idcount);
05015 for (uint i = 0; i < idcount; i++) {
05016 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
05017 }
05018
05019 uint8 cidcount = buf->ReadByte();
05020 for (uint c = 0; c < cidcount; c++) {
05021 uint8 ctype = buf->ReadByte();
05022 uint16 groupid = buf->ReadWord();
05023 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
05024
05025 if (ctype >= RTSG_END) continue;
05026
05027 extern RailtypeInfo _railtypes[RAILTYPE_END];
05028 for (uint i = 0; i < idcount; i++) {
05029 if (railtypes[i] != INVALID_RAILTYPE) {
05030 RailtypeInfo *rti = &_railtypes[railtypes[i]];
05031
05032 rti->grffile[ctype] = _cur.grffile;
05033 rti->group[ctype] = _cur.spritegroups[groupid];
05034 }
05035 }
05036 }
05037
05038
05039 buf->ReadWord();
05040 }
05041
05042 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
05043 {
05044 uint8 *airports = AllocaM(uint8, idcount);
05045 for (uint i = 0; i < idcount; i++) {
05046 airports[i] = buf->ReadByte();
05047 }
05048
05049
05050 uint8 cidcount = buf->ReadByte();
05051 buf->Skip(cidcount * 3);
05052
05053 uint16 groupid = buf->ReadWord();
05054 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
05055
05056 if (_cur.grffile->airportspec == NULL) {
05057 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
05058 return;
05059 }
05060
05061 for (uint i = 0; i < idcount; i++) {
05062 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
05063
05064 if (as == NULL) {
05065 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
05066 continue;
05067 }
05068
05069 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05070 }
05071 }
05072
05073 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
05074 {
05075 uint8 *airptiles = AllocaM(uint8, idcount);
05076 for (uint i = 0; i < idcount; i++) {
05077 airptiles[i] = buf->ReadByte();
05078 }
05079
05080
05081 uint8 cidcount = buf->ReadByte();
05082 buf->Skip(cidcount * 3);
05083
05084 uint16 groupid = buf->ReadWord();
05085 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
05086
05087 if (_cur.grffile->airtspec == NULL) {
05088 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
05089 return;
05090 }
05091
05092 for (uint i = 0; i < idcount; i++) {
05093 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
05094
05095 if (airtsp == NULL) {
05096 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
05097 continue;
05098 }
05099
05100 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05101 }
05102 }
05103
05104
05105
05106 static void FeatureMapSpriteGroup(ByteReader *buf)
05107 {
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122 uint8 feature = buf->ReadByte();
05123 uint8 idcount = buf->ReadByte();
05124
05125
05126 if (idcount == 0) {
05127
05128 buf->ReadByte();
05129 uint16 groupid = buf->ReadWord();
05130 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
05131
05132 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
05133
05134 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
05135 return;
05136 }
05137
05138
05139 SetBit(_cur.grffile->grf_features, feature);
05140
05141 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
05142
05143 switch (feature) {
05144 case GSF_TRAINS:
05145 case GSF_ROADVEHICLES:
05146 case GSF_SHIPS:
05147 case GSF_AIRCRAFT:
05148 VehicleMapSpriteGroup(buf, feature, idcount);
05149 return;
05150
05151 case GSF_CANALS:
05152 CanalMapSpriteGroup(buf, idcount);
05153 return;
05154
05155 case GSF_STATIONS:
05156 StationMapSpriteGroup(buf, idcount);
05157 return;
05158
05159 case GSF_HOUSES:
05160 TownHouseMapSpriteGroup(buf, idcount);
05161 return;
05162
05163 case GSF_INDUSTRIES:
05164 IndustryMapSpriteGroup(buf, idcount);
05165 return;
05166
05167 case GSF_INDUSTRYTILES:
05168 IndustrytileMapSpriteGroup(buf, idcount);
05169 return;
05170
05171 case GSF_CARGOES:
05172 CargoMapSpriteGroup(buf, idcount);
05173 return;
05174
05175 case GSF_AIRPORTS:
05176 AirportMapSpriteGroup(buf, idcount);
05177 return;
05178
05179 case GSF_OBJECTS:
05180 ObjectMapSpriteGroup(buf, idcount);
05181 break;
05182
05183 case GSF_RAILTYPES:
05184 RailTypeMapSpriteGroup(buf, idcount);
05185 break;
05186
05187 case GSF_AIRPORTTILES:
05188 AirportTileMapSpriteGroup(buf, idcount);
05189 return;
05190
05191 default:
05192 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
05193 return;
05194 }
05195 }
05196
05197
05198 static void FeatureNewName(ByteReader *buf)
05199 {
05200
05201
05202
05203
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216 bool new_scheme = _cur.grffile->grf_version >= 7;
05217
05218 uint8 feature = buf->ReadByte();
05219 uint8 lang = buf->ReadByte();
05220 uint8 num = buf->ReadByte();
05221 bool generic = HasBit(lang, 7);
05222 uint16 id;
05223 if (generic) {
05224 id = buf->ReadWord();
05225 } else if (feature <= GSF_AIRCRAFT) {
05226 id = buf->ReadExtendedByte();
05227 } else {
05228 id = buf->ReadByte();
05229 }
05230
05231 ClrBit(lang, 7);
05232
05233 uint16 endid = id + num;
05234
05235 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
05236 id, endid, feature, lang);
05237
05238 for (; id < endid && buf->HasData(); id++) {
05239 const char *name = buf->ReadString();
05240 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
05241
05242 switch (feature) {
05243 case GSF_TRAINS:
05244 case GSF_ROADVEHICLES:
05245 case GSF_SHIPS:
05246 case GSF_AIRCRAFT:
05247 if (!generic) {
05248 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
05249 if (e == NULL) break;
05250 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
05251 e->info.string_id = string;
05252 } else {
05253 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05254 }
05255 break;
05256
05257 case GSF_INDUSTRIES: {
05258 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05259 break;
05260 }
05261
05262 case GSF_HOUSES:
05263 default:
05264 switch (GB(id, 8, 8)) {
05265 case 0xC4:
05266 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05267 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05268 } else {
05269 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
05270 StationClass::SetName(cls_id, AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED));
05271 }
05272 break;
05273
05274 case 0xC5:
05275 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05276 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05277 } else {
05278 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05279 }
05280 break;
05281
05282 case 0xC7:
05283 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
05284 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
05285 } else {
05286 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05287 }
05288 break;
05289
05290 case 0xC9:
05291 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
05292 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
05293 } else {
05294 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05295 }
05296 break;
05297
05298 case 0xD0:
05299 case 0xD1:
05300 case 0xD2:
05301 case 0xD3:
05302 case 0xDC:
05303 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05304 break;
05305
05306 default:
05307 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
05308 break;
05309 }
05310 break;
05311 }
05312 }
05313 }
05314
05323 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
05324 {
05325
05326 if (offset >= max_sprites) {
05327 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
05328 uint orig_num = num;
05329 num = 0;
05330 return orig_num;
05331 }
05332
05333 if (offset + num > max_sprites) {
05334 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
05335 uint orig_num = num;
05336 num = max(max_sprites - offset, 0);
05337 return orig_num - num;
05338 }
05339
05340 return 0;
05341 }
05342
05343
05345 enum Action5BlockType {
05346 A5BLOCK_FIXED,
05347 A5BLOCK_ALLOW_OFFSET,
05348 A5BLOCK_INVALID,
05349 };
05351 struct Action5Type {
05352 Action5BlockType block_type;
05353 SpriteID sprite_base;
05354 uint16 min_sprites;
05355 uint16 max_sprites;
05356 const char *name;
05357 };
05358
05360 static const Action5Type _action5_types[] = {
05361
05362 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
05363 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
05364 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
05365 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
05366 { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
05367 { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
05368 { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
05369 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
05370 { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
05371 { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
05372 { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
05373 { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
05374 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
05375 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
05376 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
05377 { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
05378 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
05379 { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
05380 { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
05381 { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
05382 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
05383 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
05384 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
05385 };
05386
05387
05388 static void GraphicsNew(ByteReader *buf)
05389 {
05390
05391
05392
05393
05394
05395
05396
05397 uint8 type = buf->ReadByte();
05398 uint16 num = buf->ReadExtendedByte();
05399 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
05400 ClrBit(type, 7);
05401
05402 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
05403
05404
05405 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
05406 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++);
05407 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++);
05408 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++);
05409 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++);
05410 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++);
05411 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++);
05412 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++);
05413 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++);
05414 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++);
05415 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++);
05416 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
05417 return;
05418 }
05419
05420
05421 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
05422 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
05423 _cur.skip_sprites = num;
05424 return;
05425 }
05426
05427 const Action5Type *action5_type = &_action5_types[type];
05428
05429
05430
05431
05432 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
05433 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
05434 offset = 0;
05435 }
05436
05437
05438
05439 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
05440 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);
05441 _cur.skip_sprites = num;
05442 return;
05443 }
05444
05445
05446 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
05447 SpriteID replace = action5_type->sprite_base + offset;
05448
05449
05450 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);
05451
05452 for (; num > 0; num--) {
05453 _cur.nfo_line++;
05454 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line);
05455 }
05456
05457 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
05458
05459 _cur.skip_sprites = skip_num;
05460 }
05461
05462
05463 static void SkipAct5(ByteReader *buf)
05464 {
05465
05466 buf->ReadByte();
05467
05468
05469 _cur.skip_sprites = buf->ReadExtendedByte();
05470
05471 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
05472 }
05473
05479 void CheckForMissingSprites()
05480 {
05481
05482
05483 bool missing = false;
05484 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
05485 const Action5Type *type = &_action5_types[i];
05486 if (type->block_type == A5BLOCK_INVALID) continue;
05487
05488 for (uint j = 0; j < type->max_sprites; j++) {
05489 if (!SpriteExists(type->sprite_base + j)) {
05490 DEBUG(grf, 0, "%s sprites are missing", type->name);
05491 missing = true;
05492
05493 break;
05494 }
05495 }
05496 }
05497
05498 if (missing) {
05499 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
05500 }
05501 }
05502
05514 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
05515 {
05516 switch (param) {
05517 case 0x00:
05518 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
05519 return true;
05520
05521 case 0x01:
05522 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
05523 return true;
05524
05525 case 0x02: {
05526 YearMonthDay ymd;
05527 ConvertDateToYMD(_date, &ymd);
05528 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
05529 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
05530 return true;
05531 }
05532
05533 case 0x03:
05534 *value = _settings_game.game_creation.landscape;
05535 return true;
05536
05537 case 0x06:
05538 *value = _settings_game.vehicle.road_side << 4;
05539 return true;
05540
05541 case 0x09:
05542 *value = _date_fract * 885;
05543 return true;
05544
05545 case 0x0A:
05546 *value = _tick_counter;
05547 return true;
05548
05549 case 0x0B: {
05550 uint major = 2;
05551 uint minor = 6;
05552 uint revision = 1;
05553 uint build = 1382;
05554 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05555 return true;
05556 }
05557
05558 case 0x0D:
05559 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
05560 return true;
05561
05562 case 0x0E:
05563 *value = _cur.grffile->traininfo_vehicle_pitch;
05564 return true;
05565
05566 case 0x0F:
05567 *value = 0;
05568 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
05569 if (_settings_game.vehicle.disable_elrails) {
05570
05571 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05572 } else {
05573 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05574
05575 }
05576 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05577 return true;
05578
05579 case 0x11:
05580 *value = 0;
05581 return true;
05582
05583 case 0x12:
05584 *value = _game_mode;
05585 return true;
05586
05587
05588
05589
05590
05591
05592
05593 case 0x1A:
05594 *value = UINT_MAX;
05595 return true;
05596
05597 case 0x1B:
05598 *value = 0x3F;
05599 return true;
05600
05601 case 0x1D:
05602 *value = 1;
05603 return true;
05604
05605 case 0x1E:
05606 *value = _misc_grf_features;
05607
05608
05609 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05610 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05611 return true;
05612
05613
05614
05615 case 0x20: {
05616 byte snowline = GetSnowLine();
05617 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
05618 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
05619 } else {
05620
05621 *value = 0xFF;
05622 }
05623 return true;
05624 }
05625
05626 case 0x21:
05627 *value = _openttd_newgrf_version;
05628 return true;
05629
05630 case 0x22:
05631 *value = _settings_game.difficulty.diff_level;
05632 return true;
05633
05634 case 0x23:
05635 *value = _date;
05636 return true;
05637
05638 case 0x24:
05639 *value = _cur_year;
05640 return true;
05641
05642 default: return false;
05643 }
05644 }
05645
05646 static uint32 GetParamVal(byte param, uint32 *cond_val)
05647 {
05648
05649 uint32 value;
05650 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
05651
05652
05653 switch (param) {
05654 case 0x84: {
05655 uint32 res = 0;
05656
05657 if (_cur.stage > GLS_INIT) SetBit(res, 0);
05658 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
05659 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
05660 return res;
05661 }
05662
05663 case 0x85:
05664 if (cond_val == NULL) {
05665
05666 return 0;
05667 } else {
05668 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05669 *cond_val %= 0x20;
05670 return param_val;
05671 }
05672
05673 case 0x88:
05674 return 0;
05675
05676
05677
05678 default:
05679
05680 if (param < 0x80) return _cur.grffile->GetParam(param);
05681
05682
05683 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05684 return UINT_MAX;
05685 }
05686 }
05687
05688
05689 static void CfgApply(ByteReader *buf)
05690 {
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703 size_t pos = FioGetPos();
05704 uint16 num = FioReadWord();
05705 uint8 type = FioReadByte();
05706 byte *preload_sprite = NULL;
05707
05708
05709 if (type == 0xFF) {
05710 preload_sprite = MallocT<byte>(num);
05711 FioReadBlock(preload_sprite, num);
05712 }
05713
05714
05715 FioSeekTo(pos, SEEK_SET);
05716
05717 if (type != 0xFF) {
05718 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05719 free(preload_sprite);
05720 return;
05721 }
05722
05723 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
05724 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05725 if (it != _grf_line_to_action6_sprite_override.end()) {
05726 free(preload_sprite);
05727 preload_sprite = _grf_line_to_action6_sprite_override[location];
05728 } else {
05729 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05730 }
05731
05732
05733
05734 for (;;) {
05735 uint i;
05736 uint param_num;
05737 uint param_size;
05738 uint offset;
05739 bool add_value;
05740
05741
05742 param_num = buf->ReadByte();
05743 if (param_num == 0xFF) break;
05744
05745
05746
05747 param_size = buf->ReadByte();
05748
05749
05750
05751 add_value = HasBit(param_size, 7);
05752 param_size = GB(param_size, 0, 7);
05753
05754
05755 offset = buf->ReadExtendedByte();
05756
05757
05758
05759 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
05760 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05761 break;
05762 }
05763
05764 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05765
05766 bool carry = false;
05767 for (i = 0; i < param_size && offset + i < num; i++) {
05768 uint32 value = GetParamVal(param_num + i / 4, NULL);
05769
05770
05771 if (i % 4 == 0) carry = false;
05772
05773 if (add_value) {
05774 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05775 preload_sprite[offset + i] = GB(new_value, 0, 8);
05776
05777 carry = new_value >= 256;
05778 } else {
05779 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05780 }
05781 }
05782 }
05783 }
05784
05794 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05795 {
05796 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05797 error->data = strdup(_cur.grfconfig->GetName());
05798 }
05799
05800
05801
05802 static void SkipIf(ByteReader *buf)
05803 {
05804
05805
05806
05807
05808
05809
05810
05811
05812 uint32 cond_val = 0;
05813 uint32 mask = 0;
05814 bool result;
05815
05816 uint8 param = buf->ReadByte();
05817 uint8 paramsize = buf->ReadByte();
05818 uint8 condtype = buf->ReadByte();
05819
05820 if (condtype < 2) {
05821
05822 paramsize = 1;
05823 }
05824
05825 switch (paramsize) {
05826 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05827 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05828 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05829 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05830 default: break;
05831 }
05832
05833 if (param < 0x80 && _cur.grffile->param_end <= param) {
05834 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05835 return;
05836 }
05837
05838 uint32 param_val = GetParamVal(param, &cond_val);
05839
05840 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05841
05842
05843
05844
05845
05846
05847
05848
05849
05850 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05851
05852
05853 GRFConfig *c = GetGRFConfig(cond_val, mask);
05854
05855 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
05856 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05857 c = NULL;
05858 }
05859
05860 if (condtype != 10 && c == NULL) {
05861 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05862 return;
05863 }
05864
05865 switch (condtype) {
05866
05867 case 0x06:
05868 result = c->status == GCS_ACTIVATED;
05869 break;
05870
05871 case 0x07:
05872 result = c->status != GCS_ACTIVATED;
05873 break;
05874
05875 case 0x08:
05876 result = c->status == GCS_INITIALISED;
05877 break;
05878
05879 case 0x09:
05880 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05881 break;
05882
05883 case 0x0A:
05884
05885 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05886 break;
05887
05888 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05889 }
05890 } else {
05891
05892 switch (condtype) {
05893 case 0x00: result = !!(param_val & (1 << cond_val));
05894 break;
05895 case 0x01: result = !(param_val & (1 << cond_val));
05896 break;
05897 case 0x02: result = (param_val & mask) == cond_val;
05898 break;
05899 case 0x03: result = (param_val & mask) != cond_val;
05900 break;
05901 case 0x04: result = (param_val & mask) < cond_val;
05902 break;
05903 case 0x05: result = (param_val & mask) > cond_val;
05904 break;
05905 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05906 break;
05907 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05908 break;
05909 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
05910 break;
05911 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
05912 break;
05913
05914 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
05915 }
05916 }
05917
05918 if (!result) {
05919 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
05920 return;
05921 }
05922
05923 uint8 numsprites = buf->ReadByte();
05924
05925
05926
05927
05928
05929 GRFLabel *choice = NULL;
05930 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
05931 if (label->label != numsprites) continue;
05932
05933
05934 if (choice == NULL) choice = label;
05935
05936 if (label->nfo_line > _cur.nfo_line) {
05937 choice = label;
05938 break;
05939 }
05940 }
05941
05942 if (choice != NULL) {
05943 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
05944 FioSeekTo(choice->pos, SEEK_SET);
05945 _cur.nfo_line = choice->nfo_line;
05946 return;
05947 }
05948
05949 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
05950 _cur.skip_sprites = numsprites;
05951 if (_cur.skip_sprites == 0) {
05952
05953
05954
05955 _cur.skip_sprites = -1;
05956
05957
05958 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
05959 DisableGrf();
05960 }
05961 }
05962 }
05963
05964
05965
05966 static void ScanInfo(ByteReader *buf)
05967 {
05968 uint8 grf_version = buf->ReadByte();
05969 uint32 grfid = buf->ReadDWord();
05970 const char *name = buf->ReadString();
05971
05972 _cur.grfconfig->ident.grfid = grfid;
05973
05974 if (grf_version < 2 || grf_version > 8) {
05975 SetBit(_cur.grfconfig->flags, GCF_INVALID);
05976 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);
05977 }
05978
05979
05980 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
05981
05982 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
05983
05984 if (buf->HasData()) {
05985 const char *info = buf->ReadString();
05986 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
05987 }
05988
05989
05990 _cur.skip_sprites = -1;
05991 }
05992
05993
05994 static void GRFInfo(ByteReader *buf)
05995 {
05996
05997
05998
05999
06000
06001
06002
06003 uint8 version = buf->ReadByte();
06004 uint32 grfid = buf->ReadDWord();
06005 const char *name = buf->ReadString();
06006
06007 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
06008 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
06009 return;
06010 }
06011
06012 if (_cur.grffile->grfid != grfid) {
06013 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));
06014 _cur.grffile->grfid = grfid;
06015 }
06016
06017 _cur.grffile->grf_version = version;
06018 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
06019
06020
06021 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);
06022 }
06023
06024
06025 static void SpriteReplace(ByteReader *buf)
06026 {
06027
06028
06029
06030
06031
06032
06033
06034
06035 uint8 num_sets = buf->ReadByte();
06036
06037 for (uint i = 0; i < num_sets; i++) {
06038 uint8 num_sprites = buf->ReadByte();
06039 uint16 first_sprite = buf->ReadWord();
06040
06041 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
06042 i, num_sprites, first_sprite
06043 );
06044
06045 for (uint j = 0; j < num_sprites; j++) {
06046 int load_index = first_sprite + j;
06047 _cur.nfo_line++;
06048 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line);
06049
06050
06051
06052 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
06053 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06054 }
06055 }
06056 }
06057 }
06058
06059
06060 static void SkipActA(ByteReader *buf)
06061 {
06062 uint8 num_sets = buf->ReadByte();
06063
06064 for (uint i = 0; i < num_sets; i++) {
06065
06066 _cur.skip_sprites += buf->ReadByte();
06067
06068 buf->ReadWord();
06069 }
06070
06071 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
06072 }
06073
06074
06075 static void GRFLoadError(ByteReader *buf)
06076 {
06077
06078
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092 static const StringID msgstr[] = {
06093 STR_NEWGRF_ERROR_VERSION_NUMBER,
06094 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
06095 STR_NEWGRF_ERROR_UNSET_SWITCH,
06096 STR_NEWGRF_ERROR_INVALID_PARAMETER,
06097 STR_NEWGRF_ERROR_LOAD_BEFORE,
06098 STR_NEWGRF_ERROR_LOAD_AFTER,
06099 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
06100 };
06101
06102 static const StringID sevstr[] = {
06103 STR_NEWGRF_ERROR_MSG_INFO,
06104 STR_NEWGRF_ERROR_MSG_WARNING,
06105 STR_NEWGRF_ERROR_MSG_ERROR,
06106 STR_NEWGRF_ERROR_MSG_FATAL
06107 };
06108
06109
06110 if (_cur.grfconfig->error != NULL) return;
06111
06112 byte severity = buf->ReadByte();
06113 byte lang = buf->ReadByte();
06114 byte message_id = buf->ReadByte();
06115
06116
06117 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
06118
06119
06120
06121 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
06122 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
06123 return;
06124 }
06125 ClrBit(severity, 7);
06126
06127 if (severity >= lengthof(sevstr)) {
06128 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
06129 severity = 2;
06130 } else if (severity == 3) {
06131
06132
06133 DisableGrf();
06134 }
06135
06136 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
06137 grfmsg(7, "GRFLoadError: Invalid message id.");
06138 return;
06139 }
06140
06141 if (buf->Remaining() <= 1) {
06142 grfmsg(7, "GRFLoadError: No message data supplied.");
06143 return;
06144 }
06145
06146 GRFError *error = new GRFError(sevstr[severity]);
06147
06148 if (message_id == 0xFF) {
06149
06150 if (buf->HasData()) {
06151 const char *message = buf->ReadString();
06152
06153 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message);
06154 } else {
06155 grfmsg(7, "GRFLoadError: No custom message supplied.");
06156 error->custom_message = strdup("");
06157 }
06158 } else {
06159 error->message = msgstr[message_id];
06160 }
06161
06162 if (buf->HasData()) {
06163 const char *data = buf->ReadString();
06164
06165 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
06166 } else {
06167 grfmsg(7, "GRFLoadError: No message data supplied.");
06168 error->data = strdup("");
06169 }
06170
06171
06172 uint i = 0;
06173 for (; i < 2 && buf->HasData(); i++) {
06174 uint param_number = buf->ReadByte();
06175 error->param_value[i] = _cur.grffile->GetParam(param_number);
06176 }
06177 error->num_params = i;
06178
06179 _cur.grfconfig->error = error;
06180 }
06181
06182
06183 static void GRFComment(ByteReader *buf)
06184 {
06185
06186
06187
06188
06189 if (!buf->HasData()) return;
06190
06191 const char *text = buf->ReadString();
06192 grfmsg(2, "GRFComment: %s", text);
06193 }
06194
06195
06196 static void SafeParamSet(ByteReader *buf)
06197 {
06198 uint8 target = buf->ReadByte();
06199
06200
06201 if (target < 0x80) return;
06202
06203
06204
06205
06206
06207
06208 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06209
06210
06211 _cur.skip_sprites = -1;
06212 }
06213
06214
06215 static uint32 GetPatchVariable(uint8 param)
06216 {
06217 switch (param) {
06218
06219 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
06220
06221
06222 case 0x0E: return _settings_game.vehicle.freight_trains;
06223
06224
06225 case 0x0F: return 0;
06226
06227
06228
06229
06230 case 0x10:
06231 switch (_settings_game.vehicle.plane_speed) {
06232 default:
06233 case 4: return 1;
06234 case 3: return 2;
06235 case 2: return 2;
06236 case 1: return 4;
06237 }
06238
06239
06240
06241 case 0x11: return SPR_2CCMAP_BASE;
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254 case 0x13: {
06255 byte map_bits = 0;
06256 byte log_X = MapLogX() - 6;
06257 byte log_Y = MapLogY() - 6;
06258 byte max_edge = max(log_X, log_Y);
06259
06260 if (log_X == log_Y) {
06261 SetBit(map_bits, 0);
06262 } else {
06263 if (max_edge == log_Y) SetBit(map_bits, 1);
06264 }
06265
06266 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
06267 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
06268 }
06269
06270
06271 case 0x14:
06272 return MAX_TILE_HEIGHT;
06273
06274 default:
06275 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
06276 return 0;
06277 }
06278 }
06279
06280
06281 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
06282 {
06283 uint start = 0;
06284 uint size = 0;
06285
06286 if (op == 6) {
06287
06288 return grm[_cur.grffile->GetParam(target)];
06289 }
06290
06291
06292 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
06293
06294 for (uint i = start; i < num_ids; i++) {
06295 if (grm[i] == 0) {
06296 size++;
06297 } else {
06298 if (op == 2 || op == 3) break;
06299 start = i + 1;
06300 size = 0;
06301 }
06302
06303 if (size == count) break;
06304 }
06305
06306 if (size == count) {
06307
06308 if (op == 0 || op == 3) {
06309 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
06310 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
06311 }
06312 return start;
06313 }
06314
06315
06316 if (op != 4 && op != 5) {
06317
06318 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
06319 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06320 return UINT_MAX;
06321 }
06322
06323 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
06324 return UINT_MAX;
06325 }
06326
06327
06329 static void ParamSet(ByteReader *buf)
06330 {
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343
06344
06345
06346
06347
06348
06349
06350
06351
06352
06353 uint8 target = buf->ReadByte();
06354 uint8 oper = buf->ReadByte();
06355 uint32 src1 = buf->ReadByte();
06356 uint32 src2 = buf->ReadByte();
06357
06358 uint32 data = 0;
06359 if (buf->Remaining() >= 4) data = buf->ReadDWord();
06360
06361
06362
06363
06364
06365
06366
06367 if (HasBit(oper, 7)) {
06368 if (target < 0x80 && target < _cur.grffile->param_end) {
06369 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
06370 return;
06371 }
06372
06373 oper = GB(oper, 0, 7);
06374 }
06375
06376 if (src2 == 0xFE) {
06377 if (GB(data, 0, 8) == 0xFF) {
06378 if (data == 0x0000FFFF) {
06379
06380 src1 = GetPatchVariable(src1);
06381 } else {
06382
06383 uint8 op = src1;
06384 uint8 feature = GB(data, 8, 8);
06385 uint16 count = GB(data, 16, 16);
06386
06387 if (_cur.stage == GLS_RESERVE) {
06388 if (feature == 0x08) {
06389
06390 if (op == 0) {
06391
06392 if (_cur.spriteid + count >= 16384) {
06393 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
06394 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06395 return;
06396 }
06397
06398
06399 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
06400 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
06401 _cur.spriteid += count;
06402 }
06403 }
06404
06405 src1 = 0;
06406 } else if (_cur.stage == GLS_ACTIVATION) {
06407 switch (feature) {
06408 case 0x00:
06409 case 0x01:
06410 case 0x02:
06411 case 0x03:
06412 if (!_settings_game.vehicle.dynamic_engines) {
06413 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
06414 if (_cur.skip_sprites == -1) return;
06415 } else {
06416
06417 switch (op) {
06418 case 2:
06419 case 3:
06420 src1 = _cur.grffile->GetParam(target);
06421 break;
06422
06423 default:
06424 src1 = 0;
06425 break;
06426 }
06427 }
06428 break;
06429
06430 case 0x08:
06431 switch (op) {
06432 case 0:
06433
06434 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
06435 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
06436 break;
06437
06438 case 1:
06439 src1 = _cur.spriteid;
06440 break;
06441
06442 default:
06443 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
06444 return;
06445 }
06446 break;
06447
06448 case 0x0B:
06449
06450 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
06451 if (_cur.skip_sprites == -1) return;
06452 break;
06453
06454 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
06455 }
06456 } else {
06457
06458 src1 = 0;
06459 }
06460 }
06461 } else {
06462
06463 const GRFFile *file = GetFileByGRFID(data);
06464 GRFConfig *c = GetGRFConfig(data);
06465 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
06466
06467 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
06468 src1 = 0;
06469 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
06470 src1 = 0;
06471 } else if (src1 == 0xFE) {
06472 src1 = c->version;
06473 } else {
06474 src1 = file->GetParam(src1);
06475 }
06476 }
06477 } else {
06478
06479
06480
06481
06482
06483 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
06484 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
06485 }
06486
06487
06488
06489
06490
06491
06492
06493 uint32 res;
06494 switch (oper) {
06495 case 0x00:
06496 res = src1;
06497 break;
06498
06499 case 0x01:
06500 res = src1 + src2;
06501 break;
06502
06503 case 0x02:
06504 res = src1 - src2;
06505 break;
06506
06507 case 0x03:
06508 res = src1 * src2;
06509 break;
06510
06511 case 0x04:
06512 res = (int32)src1 * (int32)src2;
06513 break;
06514
06515 case 0x05:
06516 if ((int32)src2 < 0) {
06517 res = src1 >> -(int32)src2;
06518 } else {
06519 res = src1 << src2;
06520 }
06521 break;
06522
06523 case 0x06:
06524 if ((int32)src2 < 0) {
06525 res = (int32)src1 >> -(int32)src2;
06526 } else {
06527 res = (int32)src1 << src2;
06528 }
06529 break;
06530
06531 case 0x07:
06532 res = src1 & src2;
06533 break;
06534
06535 case 0x08:
06536 res = src1 | src2;
06537 break;
06538
06539 case 0x09:
06540 if (src2 == 0) {
06541 res = src1;
06542 } else {
06543 res = src1 / src2;
06544 }
06545 break;
06546
06547 case 0x0A:
06548 if (src2 == 0) {
06549 res = src1;
06550 } else {
06551 res = (int32)src1 / (int32)src2;
06552 }
06553 break;
06554
06555 case 0x0B:
06556 if (src2 == 0) {
06557 res = src1;
06558 } else {
06559 res = src1 % src2;
06560 }
06561 break;
06562
06563 case 0x0C:
06564 if (src2 == 0) {
06565 res = src1;
06566 } else {
06567 res = (int32)src1 % (int32)src2;
06568 }
06569 break;
06570
06571 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06572 }
06573
06574 switch (target) {
06575 case 0x8E:
06576 _cur.grffile->traininfo_vehicle_pitch = res;
06577 break;
06578
06579 case 0x8F: {
06580 extern RailtypeInfo _railtypes[RAILTYPE_END];
06581 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06582 if (_settings_game.vehicle.disable_elrails) {
06583 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06584 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06585 } else {
06586 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06587 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06588 }
06589 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06590 break;
06591 }
06592
06593
06594 case 0x93:
06595 case 0x94:
06596 case 0x95:
06597 case 0x96:
06598 case 0x97:
06599 case 0x99:
06600 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06601 break;
06602
06603 case 0x9E:
06604 _misc_grf_features = res;
06605
06606
06607 _cur.grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06608
06609
06610 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
06611 break;
06612
06613 case 0x9F:
06614 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06615 break;
06616
06617 default:
06618 if (target < 0x80) {
06619 _cur.grffile->param[target] = res;
06620
06621 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
06622 } else {
06623 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06624 }
06625 break;
06626 }
06627 }
06628
06629
06630 static void SafeGRFInhibit(ByteReader *buf)
06631 {
06632
06633
06634
06635
06636
06637 uint8 num = buf->ReadByte();
06638
06639 for (uint i = 0; i < num; i++) {
06640 uint32 grfid = buf->ReadDWord();
06641
06642
06643 if (grfid != _cur.grfconfig->ident.grfid) {
06644 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06645
06646
06647 _cur.skip_sprites = -1;
06648
06649 return;
06650 }
06651 }
06652 }
06653
06654
06655 static void GRFInhibit(ByteReader *buf)
06656 {
06657
06658
06659
06660
06661
06662 uint8 num = buf->ReadByte();
06663
06664 for (uint i = 0; i < num; i++) {
06665 uint32 grfid = buf->ReadDWord();
06666 GRFConfig *file = GetGRFConfig(grfid);
06667
06668
06669 if (file != NULL && file != _cur.grfconfig) {
06670 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06671 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06672 error->data = strdup(_cur.grfconfig->GetName());
06673 }
06674 }
06675 }
06676
06678 static void FeatureTownName(ByteReader *buf)
06679 {
06680
06681
06682
06683
06684
06685
06686
06687 uint32 grfid = _cur.grffile->grfid;
06688
06689 GRFTownName *townname = AddGRFTownName(grfid);
06690
06691 byte id = buf->ReadByte();
06692 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06693
06694 if (HasBit(id, 7)) {
06695
06696 ClrBit(id, 7);
06697 bool new_scheme = _cur.grffile->grf_version >= 7;
06698
06699 byte lang = buf->ReadByte();
06700
06701 byte nb_gen = townname->nb_gen;
06702 do {
06703 ClrBit(lang, 7);
06704
06705 const char *name = buf->ReadString();
06706
06707 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06708 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06709 free(lang_name);
06710
06711 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06712
06713 lang = buf->ReadByte();
06714 } while (lang != 0);
06715 townname->id[nb_gen] = id;
06716 townname->nb_gen++;
06717 }
06718
06719 byte nb = buf->ReadByte();
06720 grfmsg(6, "FeatureTownName: %u parts", nb);
06721
06722 townname->nbparts[id] = nb;
06723 townname->partlist[id] = CallocT<NamePartList>(nb);
06724
06725 for (int i = 0; i < nb; i++) {
06726 byte nbtext = buf->ReadByte();
06727 townname->partlist[id][i].bitstart = buf->ReadByte();
06728 townname->partlist[id][i].bitcount = buf->ReadByte();
06729 townname->partlist[id][i].maxprob = 0;
06730 townname->partlist[id][i].partcount = nbtext;
06731 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06732 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);
06733
06734 for (int j = 0; j < nbtext; j++) {
06735 byte prob = buf->ReadByte();
06736
06737 if (HasBit(prob, 7)) {
06738 byte ref_id = buf->ReadByte();
06739
06740 if (townname->nbparts[ref_id] == 0) {
06741 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06742 DelGRFTownName(grfid);
06743 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06744 return;
06745 }
06746
06747 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06748 townname->partlist[id][i].parts[j].data.id = ref_id;
06749 } else {
06750 const char *text = buf->ReadString();
06751 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06752 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06753 }
06754 townname->partlist[id][i].parts[j].prob = prob;
06755 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06756 }
06757 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06758 }
06759 }
06760
06762 static void DefineGotoLabel(ByteReader *buf)
06763 {
06764
06765
06766
06767
06768
06769 byte nfo_label = buf->ReadByte();
06770
06771 GRFLabel *label = MallocT<GRFLabel>(1);
06772 label->label = nfo_label;
06773 label->nfo_line = _cur.nfo_line;
06774 label->pos = FioGetPos();
06775 label->next = NULL;
06776
06777
06778 if (_cur.grffile->label == NULL) {
06779 _cur.grffile->label = label;
06780 } else {
06781
06782 GRFLabel *l;
06783 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
06784 l->next = label;
06785 }
06786
06787 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06788 }
06789
06790
06791 static void GRFSound(ByteReader *buf)
06792 {
06793
06794
06795
06796
06797 uint16 num = buf->ReadWord();
06798
06799 _cur.data_blocks = num;
06800 _cur.data_type = GDT_SOUND;
06801
06802 if (_cur.grffile->sound_offset == 0) {
06803 _cur.grffile->sound_offset = GetNumSounds();
06804 _cur.grffile->num_sounds = num;
06805 }
06806 }
06807
06808
06809 static void SkipAct11(ByteReader *buf)
06810 {
06811
06812
06813
06814
06815 _cur.skip_sprites = buf->ReadWord();
06816
06817 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
06818 }
06819
06820 static void ImportGRFSound(ByteReader *buf)
06821 {
06822 const GRFFile *file;
06823 SoundEntry *sound = AllocateSound();
06824 uint32 grfid = buf->ReadDWord();
06825 SoundID sound_id = buf->ReadWord();
06826
06827 file = GetFileByGRFID(grfid);
06828 if (file == NULL || file->sound_offset == 0) {
06829 grfmsg(1, "ImportGRFSound: Source file not available");
06830 return;
06831 }
06832
06833 if (sound_id >= file->num_sounds) {
06834 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06835 return;
06836 }
06837
06838 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06839
06840 *sound = *GetSound(file->sound_offset + sound_id);
06841
06842
06843 sound->volume = 128;
06844 sound->priority = 0;
06845 }
06846
06847
06848 static void GRFImportBlock(ByteReader *buf)
06849 {
06850 if (_cur.data_blocks == 0) {
06851 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
06852 return;
06853 }
06854
06855 _cur.data_blocks--;
06856
06857
06858
06859 if (buf->ReadByte() != _cur.data_type) {
06860 grfmsg(1, "GRFImportBlock: Import type mismatch");
06861 }
06862
06863 switch (_cur.data_type) {
06864 case GDT_SOUND: ImportGRFSound(buf); break;
06865 default: NOT_REACHED();
06866 }
06867 }
06868
06869 static void LoadGRFSound(ByteReader *buf)
06870 {
06871
06872
06873 SoundEntry *sound = AllocateSound();
06874
06875 if (buf->ReadDWord() != BSWAP32('RIFF')) {
06876 grfmsg(1, "LoadGRFSound: Missing RIFF header");
06877 return;
06878 }
06879
06880 uint32 total_size = buf->ReadDWord();
06881 if (total_size > buf->Remaining()) {
06882 grfmsg(1, "LoadGRFSound: RIFF was truncated");
06883 return;
06884 }
06885
06886 if (buf->ReadDWord() != BSWAP32('WAVE')) {
06887 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
06888 return;
06889 }
06890
06891 while (total_size >= 8) {
06892 uint32 tag = buf->ReadDWord();
06893 uint32 size = buf->ReadDWord();
06894 total_size -= 8;
06895 if (total_size < size) {
06896 grfmsg(1, "LoadGRFSound: Invalid RIFF");
06897 return;
06898 }
06899 total_size -= size;
06900
06901 switch (tag) {
06902 case ' tmf':
06903
06904 if (size < 16 || buf->ReadWord() != 1) {
06905 grfmsg(1, "LoadGRFSound: Invalid audio format");
06906 return;
06907 }
06908 sound->channels = buf->ReadWord();
06909 sound->rate = buf->ReadDWord();
06910 buf->ReadDWord();
06911 buf->ReadWord();
06912 sound->bits_per_sample = buf->ReadWord();
06913
06914
06915 size -= 16;
06916 break;
06917
06918 case 'atad':
06919 sound->file_size = size;
06920 sound->file_offset = FioGetPos() - buf->Remaining();
06921 sound->file_slot = _cur.file_index;
06922
06923
06924 sound->volume = 0x80;
06925 sound->priority = 0;
06926
06927 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
06928 return;
06929
06930 default:
06931
06932 break;
06933 }
06934
06935
06936 for (; size > 0; size--) buf->ReadByte();
06937 }
06938
06939 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
06940
06941
06942 MemSetT(sound, 0);
06943 }
06944
06946 static void LoadFontGlyph(ByteReader *buf)
06947 {
06948
06949
06950
06951
06952
06953
06954
06955 uint8 num_def = buf->ReadByte();
06956
06957 for (uint i = 0; i < num_def; i++) {
06958 FontSize size = (FontSize)buf->ReadByte();
06959 uint8 num_char = buf->ReadByte();
06960 uint16 base_char = buf->ReadWord();
06961
06962 if (size >= FS_END) {
06963 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
06964 }
06965
06966 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
06967
06968 for (uint c = 0; c < num_char; c++) {
06969 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
06970 _cur.nfo_line++;
06971 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
06972 }
06973 }
06974 }
06975
06977 static void SkipAct12(ByteReader *buf)
06978 {
06979
06980
06981
06982
06983
06984
06985
06986 uint8 num_def = buf->ReadByte();
06987
06988 for (uint i = 0; i < num_def; i++) {
06989
06990 buf->ReadByte();
06991
06992
06993 _cur.skip_sprites += buf->ReadByte();
06994
06995
06996 buf->ReadWord();
06997 }
06998
06999 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
07000 }
07001
07003 static void TranslateGRFStrings(ByteReader *buf)
07004 {
07005
07006
07007
07008
07009
07010
07011
07012 uint32 grfid = buf->ReadDWord();
07013 const GRFConfig *c = GetGRFConfig(grfid);
07014 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
07015 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
07016 return;
07017 }
07018
07019 if (c->status == GCS_INITIALISED) {
07020
07021
07022 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
07023
07024 char tmp[256];
07025 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
07026 error->data = strdup(tmp);
07027
07028 return;
07029 }
07030
07031
07032
07033
07034
07035
07036 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
07037 byte num_strings = buf->ReadByte();
07038 uint16 first_id = buf->ReadWord();
07039
07040 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
07041 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
07042 return;
07043 }
07044
07045 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
07046 const char *string = buf->ReadString();
07047
07048 if (StrEmpty(string)) {
07049 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
07050 continue;
07051 }
07052
07053 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
07054 }
07055 }
07056
07058 static bool ChangeGRFName(byte langid, const char *str)
07059 {
07060 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
07061 return true;
07062 }
07063
07065 static bool ChangeGRFDescription(byte langid, const char *str)
07066 {
07067 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
07068 return true;
07069 }
07070
07072 static bool ChangeGRFURL(byte langid, const char *str)
07073 {
07074 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
07075 return true;
07076 }
07077
07079 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
07080 {
07081 if (len != 1) {
07082 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
07083 buf->Skip(len);
07084 } else {
07085 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
07086 }
07087 return true;
07088 }
07089
07091 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
07092 {
07093 if (len != 1) {
07094 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
07095 buf->Skip(len);
07096 } else {
07097 char data = buf->ReadByte();
07098 GRFPalette pal = GRFP_GRF_UNSET;
07099 switch (data) {
07100 case '*':
07101 case 'A': pal = GRFP_GRF_ANY; break;
07102 case 'W': pal = GRFP_GRF_WINDOWS; break;
07103 case 'D': pal = GRFP_GRF_DOS; break;
07104 default:
07105 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
07106 break;
07107 }
07108 if (pal != GRFP_GRF_UNSET) {
07109 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
07110 _cur.grfconfig->palette |= pal;
07111 }
07112 }
07113 return true;
07114 }
07115
07117 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
07118 {
07119 if (len != 1) {
07120 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
07121 buf->Skip(len);
07122 } else {
07123 char data = buf->ReadByte();
07124 GRFPalette pal = GRFP_BLT_UNSET;
07125 switch (data) {
07126 case '8': pal = GRFP_BLT_UNSET; break;
07127 case '3': pal = GRFP_BLT_32BPP; break;
07128 default:
07129 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
07130 return true;
07131 }
07132 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
07133 _cur.grfconfig->palette |= pal;
07134 }
07135 return true;
07136 }
07137
07139 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
07140 {
07141 if (len != 4) {
07142 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
07143 buf->Skip(len);
07144 } else {
07145
07146 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07147 }
07148 return true;
07149 }
07150
07152 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
07153 {
07154 if (len != 4) {
07155 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
07156 buf->Skip(len);
07157 } else {
07158 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07159 if (_cur.grfconfig->version == 0) {
07160 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
07161 _cur.grfconfig->min_loadable_version = 0;
07162 }
07163 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
07164 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
07165 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
07166 }
07167 }
07168 return true;
07169 }
07170
07171 static GRFParameterInfo *_cur_parameter;
07172
07174 static bool ChangeGRFParamName(byte langid, const char *str)
07175 {
07176 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
07177 return true;
07178 }
07179
07181 static bool ChangeGRFParamDescription(byte langid, const char *str)
07182 {
07183 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
07184 return true;
07185 }
07186
07188 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
07189 {
07190 if (len != 1) {
07191 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
07192 buf->Skip(len);
07193 } else {
07194 GRFParameterType type = (GRFParameterType)buf->ReadByte();
07195 if (type < PTYPE_END) {
07196 _cur_parameter->type = type;
07197 } else {
07198 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
07199 }
07200 }
07201 return true;
07202 }
07203
07205 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
07206 {
07207 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
07208 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
07209 buf->Skip(len);
07210 } else if (len != 8) {
07211 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
07212 buf->Skip(len);
07213 } else {
07214 _cur_parameter->min_value = buf->ReadDWord();
07215 _cur_parameter->max_value = buf->ReadDWord();
07216 }
07217 return true;
07218 }
07219
07221 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
07222 {
07223 if (len < 1 || len > 3) {
07224 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
07225 buf->Skip(len);
07226 } else {
07227 byte param_nr = buf->ReadByte();
07228 if (param_nr >= lengthof(_cur.grfconfig->param)) {
07229 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
07230 buf->Skip(len - 1);
07231 } else {
07232 _cur_parameter->param_nr = param_nr;
07233 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
07234 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
07235 }
07236 }
07237
07238 return true;
07239 }
07240
07242 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
07243 {
07244 if (len != 4) {
07245 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
07246 buf->Skip(len);
07247 } else {
07248 _cur_parameter->def_value = buf->ReadDWord();
07249 }
07250 _cur.grfconfig->has_param_defaults = true;
07251 return true;
07252 }
07253
07254 typedef bool (*DataHandler)(size_t, ByteReader *);
07255 typedef bool (*TextHandler)(byte, const char *str);
07256 typedef bool (*BranchHandler)(ByteReader *);
07257
07265 struct AllowedSubtags {
07267 AllowedSubtags() :
07268 id(0),
07269 type(0)
07270 {}
07271
07277 AllowedSubtags(uint32 id, DataHandler handler) :
07278 id(id),
07279 type('B')
07280 {
07281 this->handler.data = handler;
07282 }
07283
07289 AllowedSubtags(uint32 id, TextHandler handler) :
07290 id(id),
07291 type('T')
07292 {
07293 this->handler.text = handler;
07294 }
07295
07301 AllowedSubtags(uint32 id, BranchHandler handler) :
07302 id(id),
07303 type('C')
07304 {
07305 this->handler.call_handler = true;
07306 this->handler.u.branch = handler;
07307 }
07308
07314 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
07315 id(id),
07316 type('C')
07317 {
07318 this->handler.call_handler = false;
07319 this->handler.u.subtags = subtags;
07320 }
07321
07322 uint32 id;
07323 byte type;
07324 union {
07325 DataHandler data;
07326 TextHandler text;
07327 struct {
07328 union {
07329 BranchHandler branch;
07330 AllowedSubtags *subtags;
07331 } u;
07332 bool call_handler;
07333 };
07334 } handler;
07335 };
07336
07337 static bool SkipUnknownInfo(ByteReader *buf, byte type);
07338 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
07339
07346 static bool ChangeGRFParamValueNames(ByteReader *buf)
07347 {
07348 byte type = buf->ReadByte();
07349 while (type != 0) {
07350 uint32 id = buf->ReadDWord();
07351 if (type != 'T' || id > _cur_parameter->max_value) {
07352 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
07353 if (!SkipUnknownInfo(buf, type)) return false;
07354 type = buf->ReadByte();
07355 continue;
07356 }
07357
07358 byte langid = buf->ReadByte();
07359 const char *name_string = buf->ReadString();
07360
07361 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
07362 if (val_name != _cur_parameter->value_names.End()) {
07363 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
07364 } else {
07365 GRFText *list = NULL;
07366 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
07367 _cur_parameter->value_names.Insert(id, list);
07368 }
07369
07370 type = buf->ReadByte();
07371 }
07372 return true;
07373 }
07374
07376 AllowedSubtags _tags_parameters[] = {
07377 AllowedSubtags('NAME', ChangeGRFParamName),
07378 AllowedSubtags('DESC', ChangeGRFParamDescription),
07379 AllowedSubtags('TYPE', ChangeGRFParamType),
07380 AllowedSubtags('LIMI', ChangeGRFParamLimits),
07381 AllowedSubtags('MASK', ChangeGRFParamMask),
07382 AllowedSubtags('VALU', ChangeGRFParamValueNames),
07383 AllowedSubtags('DFLT', ChangeGRFParamDefault),
07384 AllowedSubtags()
07385 };
07386
07393 static bool HandleParameterInfo(ByteReader *buf)
07394 {
07395 byte type = buf->ReadByte();
07396 while (type != 0) {
07397 uint32 id = buf->ReadDWord();
07398 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
07399 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
07400 if (!SkipUnknownInfo(buf, type)) return false;
07401 type = buf->ReadByte();
07402 continue;
07403 }
07404
07405 if (id >= _cur.grfconfig->param_info.Length()) {
07406 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
07407 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
07408 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
07409 }
07410 if (_cur.grfconfig->param_info[id] == NULL) {
07411 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
07412 }
07413 _cur_parameter = _cur.grfconfig->param_info[id];
07414
07415 if (!HandleNodes(buf, _tags_parameters)) return false;
07416 type = buf->ReadByte();
07417 }
07418 return true;
07419 }
07420
07422 AllowedSubtags _tags_info[] = {
07423 AllowedSubtags('NAME', ChangeGRFName),
07424 AllowedSubtags('DESC', ChangeGRFDescription),
07425 AllowedSubtags('URL_', ChangeGRFURL),
07426 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
07427 AllowedSubtags('PALS', ChangeGRFPalette),
07428 AllowedSubtags('BLTR', ChangeGRFBlitter),
07429 AllowedSubtags('VRSN', ChangeGRFVersion),
07430 AllowedSubtags('MINV', ChangeGRFMinVersion),
07431 AllowedSubtags('PARA', HandleParameterInfo),
07432 AllowedSubtags()
07433 };
07434
07436 AllowedSubtags _tags_root[] = {
07437 AllowedSubtags('INFO', _tags_info),
07438 AllowedSubtags()
07439 };
07440
07441
07448 static bool SkipUnknownInfo(ByteReader *buf, byte type)
07449 {
07450
07451 switch (type) {
07452 case 'C': {
07453 byte new_type = buf->ReadByte();
07454 while (new_type != 0) {
07455 buf->ReadDWord();
07456 if (!SkipUnknownInfo(buf, new_type)) return false;
07457 new_type = buf->ReadByte();
07458 }
07459 break;
07460 }
07461
07462 case 'T':
07463 buf->ReadByte();
07464 buf->ReadString();
07465 break;
07466
07467 case 'B': {
07468 uint16 size = buf->ReadWord();
07469 buf->Skip(size);
07470 break;
07471 }
07472
07473 default:
07474 return false;
07475 }
07476
07477 return true;
07478 }
07479
07488 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
07489 {
07490 uint i = 0;
07491 AllowedSubtags *tag;
07492 while ((tag = &subtags[i++])->type != 0) {
07493 if (tag->id != BSWAP32(id) || tag->type != type) continue;
07494 switch (type) {
07495 default: NOT_REACHED();
07496
07497 case 'T': {
07498 byte langid = buf->ReadByte();
07499 return tag->handler.text(langid, buf->ReadString());
07500 }
07501
07502 case 'B': {
07503 size_t len = buf->ReadWord();
07504 if (buf->Remaining() < len) return false;
07505 return tag->handler.data(len, buf);
07506 }
07507
07508 case 'C': {
07509 if (tag->handler.call_handler) {
07510 return tag->handler.u.branch(buf);
07511 }
07512 return HandleNodes(buf, tag->handler.u.subtags);
07513 }
07514 }
07515 }
07516 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
07517 return SkipUnknownInfo(buf, type);
07518 }
07519
07526 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
07527 {
07528 byte type = buf->ReadByte();
07529 while (type != 0) {
07530 uint32 id = buf->ReadDWord();
07531 if (!HandleNode(type, id, buf, subtags)) return false;
07532 type = buf->ReadByte();
07533 }
07534 return true;
07535 }
07536
07541 static void StaticGRFInfo(ByteReader *buf)
07542 {
07543
07544 HandleNodes(buf, _tags_root);
07545 }
07546
07548 static void GRFDataBlock(ByteReader *buf)
07549 {
07550
07551
07552 if (_cur.data_blocks == 0) {
07553 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
07554 return;
07555 }
07556
07557 uint8 name_len = buf->ReadByte();
07558 const char *name = reinterpret_cast<const char *>(buf->Data());
07559 buf->Skip(name_len);
07560
07561
07562 if (buf->ReadByte() != 0) {
07563 grfmsg(2, "GRFDataBlock: Name not properly terminated");
07564 return;
07565 }
07566
07567 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
07568
07569 _cur.data_blocks--;
07570
07571 switch (_cur.data_type) {
07572 case GDT_SOUND: LoadGRFSound(buf); break;
07573 default: NOT_REACHED();
07574 }
07575 }
07576
07582 static void GRFUnsafe(ByteReader *buf)
07583 {
07584 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
07585
07586
07587 _cur.skip_sprites = -1;
07588 }
07589
07590
07592 static void InitializeGRFSpecial()
07593 {
07594 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
07595 | (1 << 0x0D)
07596 | (1 << 0x0E)
07597 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
07598 | (0 << 0x10)
07599 | (1 << 0x12)
07600 | (1 << 0x13)
07601 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
07602 | (1 << 0x1B)
07603 | (1 << 0x1D)
07604 | (1 << 0x1E);
07605
07606 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
07607 | (1 << 0x08)
07608 | (1 << 0x09)
07609 | (0 << 0x0B)
07610 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
07611 | (1 << 0x12)
07612 | (1 << 0x13)
07613 | (1 << 0x14)
07614 | (1 << 0x16)
07615 | (1 << 0x17)
07616 | (1 << 0x18)
07617 | (1 << 0x19)
07618 | (1 << 0x1A)
07619 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
07620 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07621
07622 _ttdpatch_flags[2] = (1 << 0x01)
07623 | (1 << 0x03)
07624 | (1 << 0x0A)
07625 | (0 << 0x0B)
07626 | (0 << 0x0C)
07627 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07628 | (1 << 0x0E)
07629 | (1 << 0x0F)
07630 | (0 << 0x10)
07631 | (0 << 0x11)
07632 | (1 << 0x12)
07633 | (1 << 0x13)
07634 | (1 << 0x14)
07635 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07636 | (1 << 0x16)
07637 | (1 << 0x17)
07638 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07639 | (1 << 0x19)
07640 | (1 << 0x1A)
07641 | (1 << 0x1B)
07642 | (1 << 0x1C)
07643 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07644 | (1 << 0x1E)
07645 | (0 << 0x1F);
07646
07647 _ttdpatch_flags[3] = (0 << 0x00)
07648 | (1 << 0x01)
07649 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07650 | (1 << 0x03)
07651 | (0 << 0x04)
07652 | (1 << 0x05)
07653 | (1 << 0x06)
07654 | (1 << 0x07)
07655 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07656 | (0 << 0x09)
07657 | (0 << 0x0A)
07658 | (1 << 0x0B)
07659 | (1 << 0x0C)
07660 | (1 << 0x0D)
07661 | (1 << 0x0E)
07662 | (1 << 0x0F)
07663 | (1 << 0x10)
07664 | (1 << 0x11)
07665 | (1 << 0x12)
07666 | (0 << 0x13)
07667 | (1 << 0x14)
07668 | (0 << 0x15)
07669 | (1 << 0x16)
07670 | (1 << 0x17)
07671 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07672 | (1 << 0x1E)
07673 | (1 << 0x1F);
07674 }
07675
07677 static void ResetCustomStations()
07678 {
07679 const GRFFile * const *end = _grf_files.End();
07680 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07681 StationSpec **&stations = (*file)->stations;
07682 if (stations == NULL) continue;
07683 for (uint i = 0; i < MAX_STATIONS; i++) {
07684 if (stations[i] == NULL) continue;
07685 StationSpec *statspec = stations[i];
07686
07687 delete[] statspec->renderdata;
07688
07689
07690 if (!statspec->copied_layouts) {
07691 for (uint l = 0; l < statspec->lengths; l++) {
07692 for (uint p = 0; p < statspec->platforms[l]; p++) {
07693 free(statspec->layouts[l][p]);
07694 }
07695 free(statspec->layouts[l]);
07696 }
07697 free(statspec->layouts);
07698 free(statspec->platforms);
07699 }
07700
07701
07702 free(statspec);
07703 }
07704
07705
07706 free(stations);
07707 stations = NULL;
07708 }
07709 }
07710
07712 static void ResetCustomHouses()
07713 {
07714 const GRFFile * const *end = _grf_files.End();
07715 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07716 HouseSpec **&housespec = (*file)->housespec;
07717 if (housespec == NULL) continue;
07718 for (uint i = 0; i < HOUSE_MAX; i++) {
07719 free(housespec[i]);
07720 }
07721
07722 free(housespec);
07723 housespec = NULL;
07724 }
07725 }
07726
07728 static void ResetCustomAirports()
07729 {
07730 const GRFFile * const *end = _grf_files.End();
07731 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07732 AirportSpec **aslist = (*file)->airportspec;
07733 if (aslist != NULL) {
07734 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07735 AirportSpec *as = aslist[i];
07736
07737 if (as != NULL) {
07738
07739 for (int j = 0; j < as->num_table; j++) {
07740
07741 free(as->table[j]);
07742 }
07743 free(as->table);
07744 free(as->depot_table);
07745
07746 free(as);
07747 }
07748 }
07749 free(aslist);
07750 (*file)->airportspec = NULL;
07751 }
07752
07753 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07754 if (airporttilespec != NULL) {
07755 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07756 free(airporttilespec[i]);
07757 }
07758 free(airporttilespec);
07759 airporttilespec = NULL;
07760 }
07761 }
07762 }
07763
07765 static void ResetCustomIndustries()
07766 {
07767 const GRFFile * const *end = _grf_files.End();
07768 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07769 IndustrySpec **&industryspec = (*file)->industryspec;
07770 IndustryTileSpec **&indtspec = (*file)->indtspec;
07771
07772
07773
07774 if (industryspec != NULL) {
07775 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07776 IndustrySpec *ind = industryspec[i];
07777 if (ind == NULL) continue;
07778
07779
07780 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07781 free(ind->random_sounds);
07782 }
07783
07784
07785 CleanIndustryTileTable(ind);
07786
07787 free(ind);
07788 }
07789
07790 free(industryspec);
07791 industryspec = NULL;
07792 }
07793
07794 if (indtspec == NULL) continue;
07795 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07796 free(indtspec[i]);
07797 }
07798
07799 free(indtspec);
07800 indtspec = NULL;
07801 }
07802 }
07803
07805 static void ResetCustomObjects()
07806 {
07807 const GRFFile * const *end = _grf_files.End();
07808 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07809 ObjectSpec **&objectspec = (*file)->objectspec;
07810 if (objectspec == NULL) continue;
07811 for (uint i = 0; i < NUM_OBJECTS; i++) {
07812 free(objectspec[i]);
07813 }
07814
07815 free(objectspec);
07816 objectspec = NULL;
07817 }
07818 }
07819
07821 static void ResetNewGRF()
07822 {
07823 const GRFFile * const *end = _grf_files.End();
07824 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07825 GRFFile *f = *file;
07826 free(f->filename);
07827 free(f->cargo_list);
07828 free(f->railtype_list);
07829 delete [] f->language_map;
07830 free(f);
07831 }
07832
07833 _grf_files.Clear();
07834 _cur.grffile = NULL;
07835 }
07836
07838 static void ResetNewGRFErrors()
07839 {
07840 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07841 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07842 delete c->error;
07843 c->error = NULL;
07844 }
07845 }
07846 }
07847
07852 void ResetNewGRFData()
07853 {
07854 CleanUpStrings();
07855 CleanUpGRFTownNames();
07856
07857
07858 SetupEngines();
07859
07860
07861 ResetBridges();
07862
07863
07864 ResetRailTypes();
07865
07866
07867 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07868
07869
07870 Engine *e;
07871 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07872 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07873 }
07874
07875
07876 memset(&_grm_engines, 0, sizeof(_grm_engines));
07877 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
07878
07879
07880 ResetGenericCallbacks();
07881
07882
07883 ResetPriceBaseMultipliers();
07884
07885
07886 ResetCurrencies();
07887
07888
07889 ResetCustomHouses();
07890 ResetHouses();
07891
07892
07893 ResetCustomIndustries();
07894 ResetIndustries();
07895
07896
07897 ObjectClass::Reset();
07898 ResetCustomObjects();
07899 ResetObjects();
07900
07901
07902 StationClass::Reset();
07903 ResetCustomStations();
07904
07905
07906 AirportClass::Reset();
07907 ResetCustomAirports();
07908 AirportSpec::ResetAirports();
07909 AirportTileSpec::ResetAirportTiles();
07910
07911
07912 memset(_water_feature, 0, sizeof(_water_feature));
07913
07914
07915 ClearSnowLine();
07916
07917
07918 ResetNewGRF();
07919
07920
07921 ResetNewGRFErrors();
07922
07923
07924 SetupCargoForClimate(_settings_game.game_creation.landscape);
07925
07926
07927 _misc_grf_features = 0;
07928
07929 _loaded_newgrf_features.has_2CC = false;
07930 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07931 _loaded_newgrf_features.has_newhouses = false;
07932 _loaded_newgrf_features.has_newindustries = false;
07933 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07934
07935
07936 _grf_id_overrides.clear();
07937
07938 InitializeSoundPool();
07939 _spritegroup_pool.CleanPool();
07940 }
07941
07945 void ResetPersistentNewGRFData()
07946 {
07947
07948 _engine_mngr.ResetToDefaultMapping();
07949 _house_mngr.ResetMapping();
07950 _industry_mngr.ResetMapping();
07951 _industile_mngr.ResetMapping();
07952 _airport_mngr.ResetMapping();
07953 _airporttile_mngr.ResetMapping();
07954 }
07955
07960 static void BuildCargoTranslationMap()
07961 {
07962 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
07963
07964 for (CargoID c = 0; c < NUM_CARGO; c++) {
07965 const CargoSpec *cs = CargoSpec::Get(c);
07966 if (!cs->IsValid()) continue;
07967
07968 if (_cur.grffile->cargo_max == 0) {
07969
07970 _cur.grffile->cargo_map[c] = cs->bitnum;
07971 } else {
07972
07973 for (uint i = 0; i < _cur.grffile->cargo_max; i++) {
07974 if (cs->label == _cur.grffile->cargo_list[i]) {
07975 _cur.grffile->cargo_map[c] = i;
07976 break;
07977 }
07978 }
07979 }
07980 }
07981 }
07982
07987 static void InitNewGRFFile(const GRFConfig *config)
07988 {
07989 GRFFile *newfile = GetFileByFilename(config->filename);
07990 if (newfile != NULL) {
07991
07992 _cur.grffile = newfile;
07993 return;
07994 }
07995
07996 newfile = CallocT<GRFFile>(1);
07997
07998 newfile->filename = strdup(config->filename);
07999 newfile->grfid = config->ident.grfid;
08000
08001
08002 newfile->traininfo_vehicle_pitch = 0;
08003 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
08004
08005
08006 for (Price i = PR_BEGIN; i < PR_END; i++) {
08007 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
08008 }
08009
08010
08011 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
08012 newfile->railtype_map[0] = RAILTYPE_RAIL;
08013 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
08014 newfile->railtype_map[2] = RAILTYPE_MONO;
08015 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
08016
08017
08018
08019 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
08020 memset(newfile->param, 0, sizeof(newfile->param));
08021
08022 assert(config->num_params <= lengthof(config->param));
08023 newfile->param_end = config->num_params;
08024 if (newfile->param_end > 0) {
08025 MemCpyT(newfile->param, config->param, newfile->param_end);
08026 }
08027
08028 *_grf_files.Append() = _cur.grffile = newfile;
08029 }
08030
08031
08036 static const CargoLabel _default_refitmasks_rail[] = {
08037 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
08038 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
08039 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08040 'PLST', 'FZDR',
08041 0 };
08042
08043 static const CargoLabel _default_refitmasks_road[] = {
08044 0 };
08045
08046 static const CargoLabel _default_refitmasks_ships[] = {
08047 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
08048 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
08049 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08050 'PLST', 'FZDR',
08051 0 };
08052
08053 static const CargoLabel _default_refitmasks_aircraft[] = {
08054 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
08055 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
08056 0 };
08057
08058 static const CargoLabel * const _default_refitmasks[] = {
08059 _default_refitmasks_rail,
08060 _default_refitmasks_road,
08061 _default_refitmasks_ships,
08062 _default_refitmasks_aircraft,
08063 };
08064
08065
08069 static void CalculateRefitMasks()
08070 {
08071 Engine *e;
08072
08073 FOR_ALL_ENGINES(e) {
08074 EngineID engine = e->index;
08075 EngineInfo *ei = &e->info;
08076 bool only_defaultcargo;
08077 const uint8 *cargo_map_for_first_refittable = NULL;
08078
08079
08080 if (_gted[engine].refitmask_valid) {
08081 uint32 mask = 0;
08082 uint32 not_mask = 0;
08083 uint32 xor_mask = 0;
08084
08085
08086
08087 only_defaultcargo = (ei->refit_mask == 0 && _gted[engine].cargo_allowed == 0 && _gted[engine].ctt_include_mask == 0);
08088
08089 const GRFFile *file = _gted[engine].refitmask_grf;
08090 if (file == NULL) file = e->GetGRF();
08091 if (file != NULL && file->grf_version >= 8 && file->cargo_max != 0) {
08092 cargo_map_for_first_refittable = file->cargo_map;
08093 }
08094
08095 if (ei->refit_mask != 0) {
08096 if (file != NULL && file->cargo_max != 0) {
08097
08098 uint num_cargo = min(32, file->cargo_max);
08099 for (uint i = 0; i < num_cargo; i++) {
08100 if (!HasBit(ei->refit_mask, i)) continue;
08101
08102 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
08103 if (c == CT_INVALID) continue;
08104
08105 SetBit(xor_mask, c);
08106 }
08107 } else {
08108
08109 const CargoSpec *cs;
08110 FOR_ALL_CARGOSPECS(cs) {
08111 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
08112 }
08113 }
08114 }
08115
08116 if (_gted[engine].cargo_allowed != 0) {
08117
08118 const CargoSpec *cs;
08119 FOR_ALL_CARGOSPECS(cs) {
08120 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
08121 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
08122 }
08123 }
08124
08125 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
08126
08127
08128 ei->refit_mask |= _gted[engine].ctt_include_mask;
08129 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
08130 } else {
08131 uint32 xor_mask = 0;
08132
08133
08134 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
08135 const CargoLabel *cl = _default_refitmasks[e->type];
08136 for (uint i = 0;; i++) {
08137 if (cl[i] == 0) break;
08138
08139 CargoID cargo = GetCargoIDByLabel(cl[i]);
08140 if (cargo == CT_INVALID) continue;
08141
08142 SetBit(xor_mask, cargo);
08143 }
08144 }
08145
08146 ei->refit_mask = xor_mask & _cargo_mask;
08147
08148
08149 only_defaultcargo = (ei->refit_mask == 0);
08150 }
08151
08152
08153
08154 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
08155 ei->cargo_type = CT_INVALID;
08156 }
08157
08158
08159
08160 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
08161 if (cargo_map_for_first_refittable == NULL) {
08162
08163 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
08164 } else {
08165
08166 byte best_local_slot = 0xFF;
08167 CargoID cargo_type;
08168 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
08169 byte local_slot = cargo_map_for_first_refittable[cargo_type];
08170 if (local_slot < best_local_slot) {
08171 best_local_slot = local_slot;
08172 ei->cargo_type = cargo_type;
08173 }
08174 }
08175 }
08176 }
08177 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
08178
08179
08180 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
08181 ei->refit_mask = 0;
08182 }
08183 }
08184 }
08185
08187 static void FinaliseCanals()
08188 {
08189 for (uint i = 0; i < CF_END; i++) {
08190 if (_water_feature[i].grffile != NULL) {
08191 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
08192 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
08193 }
08194 }
08195 }
08196
08198 static void FinaliseEngineArray()
08199 {
08200 Engine *e;
08201
08202 FOR_ALL_ENGINES(e) {
08203 if (e->GetGRF() == NULL) {
08204 const EngineIDMapping &eid = _engine_mngr[e->index];
08205 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
08206 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
08207 }
08208 }
08209
08210
08211
08212
08213 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
08214 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
08215 }
08216
08217
08218 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
08219 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
08220 SetBit(_loaded_newgrf_features.used_liveries, ls);
08221
08222
08223 if (e->type == VEH_TRAIN) {
08224 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
08225 switch (ls) {
08226 case LS_STEAM:
08227 case LS_DIESEL:
08228 case LS_ELECTRIC:
08229 case LS_MONORAIL:
08230 case LS_MAGLEV:
08231 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
08232 break;
08233
08234 case LS_DMU:
08235 case LS_EMU:
08236 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
08237 break;
08238
08239 default: NOT_REACHED();
08240 }
08241 }
08242 }
08243 }
08244 }
08245
08247 static void FinaliseCargoArray()
08248 {
08249 for (CargoID c = 0; c < NUM_CARGO; c++) {
08250 CargoSpec *cs = CargoSpec::Get(c);
08251 if (!cs->IsValid()) {
08252 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
08253 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
08254 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
08255 }
08256 }
08257 }
08258
08270 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
08271 {
08272 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
08273 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
08274 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
08275 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
08276 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
08277 hs->enabled = false;
08278 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);
08279 return false;
08280 }
08281
08282
08283
08284
08285 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
08286 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
08287 hs->enabled = false;
08288 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);
08289 return false;
08290 }
08291
08292
08293
08294 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
08295 hs->enabled = false;
08296 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);
08297 return false;
08298 }
08299
08300
08301 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
08302 hs->enabled = false;
08303 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);
08304 return false;
08305 }
08306
08307 return true;
08308 }
08309
08316 static void EnsureEarlyHouse(HouseZones bitmask)
08317 {
08318 Year min_year = MAX_YEAR;
08319
08320 for (int i = 0; i < HOUSE_MAX; i++) {
08321 HouseSpec *hs = HouseSpec::Get(i);
08322 if (hs == NULL || !hs->enabled) continue;
08323 if ((hs->building_availability & bitmask) != bitmask) continue;
08324 if (hs->min_year < min_year) min_year = hs->min_year;
08325 }
08326
08327 if (min_year == 0) return;
08328
08329 for (int i = 0; i < HOUSE_MAX; i++) {
08330 HouseSpec *hs = HouseSpec::Get(i);
08331 if (hs == NULL || !hs->enabled) continue;
08332 if ((hs->building_availability & bitmask) != bitmask) continue;
08333 if (hs->min_year == min_year) hs->min_year = 0;
08334 }
08335 }
08336
08343 static void FinaliseHouseArray()
08344 {
08345
08346
08347
08348
08349
08350
08351
08352
08353
08354 const GRFFile * const *end = _grf_files.End();
08355 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08356 HouseSpec **&housespec = (*file)->housespec;
08357 if (housespec == NULL) continue;
08358
08359 for (int i = 0; i < HOUSE_MAX; i++) {
08360 HouseSpec *hs = housespec[i];
08361
08362 if (hs == NULL) continue;
08363
08364 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
08365 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
08366 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
08367
08368 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
08369
08370 _house_mngr.SetEntitySpec(hs);
08371 }
08372 }
08373
08374 for (int i = 0; i < HOUSE_MAX; i++) {
08375 HouseSpec *hs = HouseSpec::Get(i);
08376 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
08377 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
08378 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
08379
08380
08381
08382 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
08383
08384
08385
08386
08387
08388
08389
08390 hs->building_flags = TILE_NO_FLAG;
08391 }
08392 }
08393
08394 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
08395 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
08396 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
08397 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
08398 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
08399 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
08400
08401 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
08402 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
08403 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
08404 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
08405 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
08406 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
08407 }
08408 }
08409
08415 static void FinaliseIndustriesArray()
08416 {
08417 const GRFFile * const *end = _grf_files.End();
08418 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08419 IndustrySpec **&industryspec = (*file)->industryspec;
08420 IndustryTileSpec **&indtspec = (*file)->indtspec;
08421 if (industryspec != NULL) {
08422 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
08423 IndustrySpec *indsp = industryspec[i];
08424
08425 if (indsp != NULL && indsp->enabled) {
08426 StringID strid;
08427
08428
08429
08430 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
08431 if (strid != STR_UNDEFINED) indsp->name = strid;
08432
08433 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
08434 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
08435
08436 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
08437 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
08438
08439 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
08440 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
08441
08442 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
08443 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
08444
08445 if (indsp->station_name != STR_NULL) {
08446
08447
08448 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
08449 if (strid != STR_UNDEFINED) indsp->station_name = strid;
08450 }
08451
08452 _industry_mngr.SetEntitySpec(indsp);
08453 _loaded_newgrf_features.has_newindustries = true;
08454 }
08455 }
08456 }
08457
08458 if (indtspec != NULL) {
08459 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
08460 IndustryTileSpec *indtsp = indtspec[i];
08461 if (indtsp != NULL) {
08462 _industile_mngr.SetEntitySpec(indtsp);
08463 }
08464 }
08465 }
08466 }
08467
08468 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
08469 IndustrySpec *indsp = &_industry_specs[j];
08470 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
08471 for (uint i = 0; i < 3; i++) {
08472 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
08473 }
08474 }
08475 if (!indsp->enabled) {
08476 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
08477 }
08478 }
08479 }
08480
08486 static void FinaliseObjectsArray()
08487 {
08488 const GRFFile * const *end = _grf_files.End();
08489 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08490 ObjectSpec **&objectspec = (*file)->objectspec;
08491 if (objectspec != NULL) {
08492 for (int i = 0; i < NUM_OBJECTS; i++) {
08493 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
08494 _object_mngr.SetEntitySpec(objectspec[i]);
08495 }
08496 }
08497 }
08498 }
08499 }
08500
08506 static void FinaliseAirportsArray()
08507 {
08508 const GRFFile * const *end = _grf_files.End();
08509 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08510 AirportSpec **&airportspec = (*file)->airportspec;
08511 if (airportspec != NULL) {
08512 for (int i = 0; i < NUM_AIRPORTS; i++) {
08513 if (airportspec[i] != NULL && airportspec[i]->enabled) {
08514 _airport_mngr.SetEntitySpec(airportspec[i]);
08515 }
08516 }
08517 }
08518
08519 AirportTileSpec **&airporttilespec = (*file)->airtspec;
08520 if (airporttilespec != NULL) {
08521 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
08522 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
08523 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
08524 }
08525 }
08526 }
08527 }
08528 }
08529
08530
08531
08532
08533
08534
08535
08536 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
08537 {
08538
08539
08540
08541
08542
08543
08544
08545
08546
08547
08548
08549
08550 static const SpecialSpriteHandler handlers[][GLS_END] = {
08551 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
08552 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
08553 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
08554 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
08555 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
08556 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
08557 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
08558 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
08559 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
08560 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
08561 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
08562 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
08563 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
08564 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
08565 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
08566 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
08567 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
08568 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
08569 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
08570 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
08571 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
08572 };
08573
08574 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
08575
08576 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
08577 if (it == _grf_line_to_action6_sprite_override.end()) {
08578
08579
08580 FioReadBlock(buf, num);
08581 } else {
08582
08583 buf = _grf_line_to_action6_sprite_override[location];
08584 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
08585
08586
08587 FioSeekTo(num, SEEK_CUR);
08588 }
08589
08590 ByteReader br(buf, buf + num);
08591 ByteReader *bufp = &br;
08592
08593 try {
08594 byte action = bufp->ReadByte();
08595
08596 if (action == 0xFF) {
08597 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
08598 GRFDataBlock(bufp);
08599 } else if (action == 0xFE) {
08600 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
08601 GRFImportBlock(bufp);
08602 } else if (action >= lengthof(handlers)) {
08603 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
08604 } else if (handlers[action][stage] == NULL) {
08605 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
08606 } else {
08607 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
08608 handlers[action][stage](bufp);
08609 }
08610 } catch (...) {
08611 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
08612 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
08613 }
08614 }
08615
08616
08624 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
08625 {
08626 const char *filename = config->filename;
08627 uint16 num;
08628
08629
08630
08631
08632
08633
08634
08635
08636
08637
08638 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
08639 _cur.grffile = GetFileByFilename(filename);
08640 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
08641 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
08642 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
08643 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
08644 }
08645
08646 if (file_index > LAST_GRF_SLOT) {
08647 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
08648 config->status = GCS_DISABLED;
08649 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
08650 return;
08651 }
08652
08653 FioOpenFile(file_index, filename, subdir);
08654 _cur.file_index = file_index;
08655 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
08656
08657 _cur.grfconfig = config;
08658
08659 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
08660
08661
08662
08663
08664 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
08665 FioReadDword();
08666 } else {
08667 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08668 return;
08669 }
08670
08671 _cur.ClearDataForNextFile();
08672
08673 ReusableBuffer<byte> buf;
08674
08675 while ((num = FioReadWord()) != 0) {
08676 byte type = FioReadByte();
08677 _cur.nfo_line++;
08678
08679 if (type == 0xFF) {
08680 if (_cur.skip_sprites == 0) {
08681 DecodeSpecialSprite(buf.Allocate(num), num, stage);
08682
08683
08684 if (_cur.skip_sprites == -1) break;
08685
08686 continue;
08687 } else {
08688 FioSkipBytes(num);
08689 }
08690 } else {
08691 if (_cur.skip_sprites == 0) {
08692 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08693 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08694 break;
08695 }
08696
08697 FioSkipBytes(7);
08698 SkipSpriteData(type, num - 8);
08699 }
08700
08701 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
08702 }
08703 }
08704
08712 static void ActivateOldShore()
08713 {
08714
08715
08716 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08717
08718 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08719 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08720 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08721 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08722 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08723 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08724 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08725 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08726 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08727 }
08728
08729 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08730 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08731 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08732 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08733 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08734 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08735 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08736 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08737 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08738
08739
08740
08741 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08742 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08743 }
08744 }
08745
08749 static void FinalisePriceBaseMultipliers()
08750 {
08751 extern const PriceBaseSpec _price_base_specs[];
08753 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08754
08755
08756 int num_grfs = _grf_files.Length();
08757 int *grf_overrides = AllocaM(int, num_grfs);
08758 for (int i = 0; i < num_grfs; i++) {
08759 grf_overrides[i] = -1;
08760
08761 GRFFile *source = _grf_files[i];
08762 uint32 override = _grf_id_overrides[source->grfid];
08763 if (override == 0) continue;
08764
08765 GRFFile *dest = GetFileByGRFID(override);
08766 if (dest == NULL) continue;
08767
08768 grf_overrides[i] = _grf_files.FindIndex(dest);
08769 assert(grf_overrides[i] >= 0);
08770 }
08771
08772
08773 for (int i = 0; i < num_grfs; i++) {
08774 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08775 GRFFile *source = _grf_files[i];
08776 GRFFile *dest = _grf_files[grf_overrides[i]];
08777
08778 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08779 source->grf_features |= features;
08780 dest->grf_features |= features;
08781
08782 for (Price p = PR_BEGIN; p < PR_END; p++) {
08783
08784 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08785 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08786 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08787 }
08788 }
08789
08790
08791 for (int i = num_grfs - 1; i >= 0; 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) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08803 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08804 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08805 }
08806 }
08807
08808
08809 for (int i = 0; i < num_grfs; i++) {
08810 if (grf_overrides[i] < 0) 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 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08820 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08821 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08822 }
08823 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08824 }
08825 }
08826
08827
08828 const GRFFile * const *end = _grf_files.End();
08829 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08830 if ((*file)->grf_version >= 8) continue;
08831 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08832 for (Price p = PR_BEGIN; p < PR_END; p++) {
08833 Price fallback_price = _price_base_specs[p].fallback_price;
08834 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08835
08836
08837 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08838 }
08839 }
08840 }
08841
08842
08843 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08844 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08845 for (Price p = PR_BEGIN; p < PR_END; p++) {
08846 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08847
08848 price_base_multipliers[p] = 0;
08849 } else {
08850 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08851
08852
08853 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08854 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08855 price_base_multipliers[p] = 0;
08856 } else {
08857 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08858 }
08859 }
08860 }
08861 }
08862 }
08863
08864 void InitDepotWindowBlockSizes();
08865
08866 extern void InitGRFTownGeneratorNames();
08867
08869 static void AfterLoadGRFs()
08870 {
08871 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08872 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08873 }
08874 _string_to_grf_mapping.clear();
08875
08876
08877 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08878 free((*it).second);
08879 }
08880 _grf_line_to_action6_sprite_override.clear();
08881
08882
08883 FinaliseCargoArray();
08884
08885
08886 CalculateRefitMasks();
08887
08888
08889 FinaliseEngineArray();
08890
08891
08892 FinaliseCanals();
08893
08894
08895 InitDepotWindowBlockSizes();
08896
08897
08898 FinaliseHouseArray();
08899
08900
08901 FinaliseIndustriesArray();
08902
08903
08904 FinaliseObjectsArray();
08905
08906 InitializeSortedCargoSpecs();
08907
08908
08909 SortIndustryTypes();
08910
08911
08912 BuildIndustriesLegend();
08913
08914
08915 BuildLinkStatsLegend();
08916
08917
08918 FinaliseAirportsArray();
08919 BindAirportSpecs();
08920
08921
08922 InitGRFTownGeneratorNames();
08923
08924
08925 CommitVehicleListOrderChanges();
08926
08927
08928 ActivateOldShore();
08929
08930
08931 InitRailTypes();
08932
08933 Engine *e;
08934 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
08935 if (_gted[e->index].rv_max_speed != 0) {
08936
08937 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
08938 }
08939 }
08940
08941 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
08942 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
08943 if (railtype == INVALID_RAILTYPE) {
08944
08945 e->info.climates = 0;
08946 } else {
08947 e->u.rail.railtype = railtype;
08948 }
08949 }
08950
08951 SetYearEngineAgingStops();
08952
08953 FinalisePriceBaseMultipliers();
08954
08955
08956 free(_gted);
08957 _grm_sprites.clear();
08958 }
08959
08965 void LoadNewGRF(uint load_index, uint file_index)
08966 {
08967
08968
08969
08970
08971 Date date = _date;
08972 Year year = _cur_year;
08973 DateFract date_fract = _date_fract;
08974 uint16 tick_counter = _tick_counter;
08975 byte display_opt = _display_opt;
08976
08977 if (_networking) {
08978 _cur_year = _settings_game.game_creation.starting_year;
08979 _date = ConvertYMDToDate(_cur_year, 0, 1);
08980 _date_fract = 0;
08981 _tick_counter = 0;
08982 _display_opt = 0;
08983 }
08984
08985 InitializeGRFSpecial();
08986
08987 ResetNewGRFData();
08988
08989
08990
08991
08992
08993
08994
08995
08996 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08997 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
08998 }
08999
09000 _cur.spriteid = load_index;
09001
09002
09003
09004
09005 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
09006
09007
09008 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09009 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
09010 }
09011
09012 if (stage == GLS_RESERVE) {
09013 static const uint32 overrides[][2] = {
09014 { 0x44442202, 0x44440111 },
09015 { 0x6D620402, 0x6D620401 },
09016 { 0x4D656f20, 0x4D656F17 },
09017 };
09018 for (size_t i = 0; i < lengthof(overrides); i++) {
09019 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
09020 }
09021 }
09022
09023 uint slot = file_index;
09024
09025 _cur.stage = stage;
09026 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09027 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
09028 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
09029
09030 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
09031 if (!FioCheckFileExists(c->filename, subdir)) {
09032 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
09033 c->status = GCS_NOT_FOUND;
09034 continue;
09035 }
09036
09037 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
09038 LoadNewGRFFile(c, slot++, stage, subdir);
09039 if (stage == GLS_RESERVE) {
09040 SetBit(c->flags, GCF_RESERVED);
09041 } else if (stage == GLS_ACTIVATION) {
09042 ClrBit(c->flags, GCF_RESERVED);
09043 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
09044 ClearTemporaryNewGRFData(_cur.grffile);
09045 BuildCargoTranslationMap();
09046 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
09047 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
09048
09049 ClearTemporaryNewGRFData(_cur.grffile);
09050 }
09051 }
09052 }
09053
09054
09055 _cur.ClearDataForNextFile();
09056
09057
09058 AfterLoadGRFs();
09059
09060
09061 _cur_year = year;
09062 _date = date;
09063 _date_fract = date_fract;
09064 _tick_counter = tick_counter;
09065 _display_opt = display_opt;
09066 }