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