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