00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013
00014 #include <stdarg.h>
00015
00016 #include "debug.h"
00017 #include "fileio_func.h"
00018 #include "engine_func.h"
00019 #include "engine_base.h"
00020 #include "bridge.h"
00021 #include "town.h"
00022 #include "newgrf_engine.h"
00023 #include "newgrf_text.h"
00024 #include "fontcache.h"
00025 #include "currency.h"
00026 #include "landscape.h"
00027 #include "newgrf_cargo.h"
00028 #include "newgrf_house.h"
00029 #include "newgrf_sound.h"
00030 #include "newgrf_station.h"
00031 #include "industrytype.h"
00032 #include "newgrf_canal.h"
00033 #include "newgrf_townname.h"
00034 #include "newgrf_industries.h"
00035 #include "newgrf_airporttiles.h"
00036 #include "newgrf_airport.h"
00037 #include "newgrf_object.h"
00038 #include "rev.h"
00039 #include "fios.h"
00040 #include "strings_func.h"
00041 #include "date_func.h"
00042 #include "string_func.h"
00043 #include "network/network.h"
00044 #include <map>
00045 #include "smallmap_gui.h"
00046 #include "genworld.h"
00047 #include "error.h"
00048 #include "vehicle_func.h"
00049 #include "language.h"
00050 #include "vehicle_base.h"
00051
00052 #include "table/strings.h"
00053 #include "table/build_industry.h"
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00065 static SmallVector<GRFFile *, 16> _grf_files;
00066
00068 byte _misc_grf_features = 0;
00069
00071 static uint32 _ttdpatch_flags[8];
00072
00074 GRFLoadedFeatures _loaded_newgrf_features;
00075
00076 enum GrfDataType {
00077 GDT_SOUND,
00078 };
00079
00080 static const uint MAX_SPRITEGROUP = UINT8_MAX;
00081
00083 struct GrfProcessingState {
00084 private:
00086 struct SpriteSet {
00087 SpriteID sprite;
00088 uint num_sprites;
00089 };
00090
00092 std::map<uint, SpriteSet> spritesets[GSF_END];
00093
00094 public:
00095
00096 GrfLoadingStage stage;
00097 SpriteID spriteid;
00098
00099
00100 uint file_index;
00101 GRFFile *grffile;
00102 GRFConfig *grfconfig;
00103 uint32 nfo_line;
00104
00105
00106 int skip_sprites;
00107 byte data_blocks;
00108 GrfDataType data_type;
00109
00110
00111 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
00112
00114 void ClearDataForNextFile()
00115 {
00116 this->nfo_line = 0;
00117 this->skip_sprites = 0;
00118 this->data_blocks = 0;
00119
00120 for (uint i = 0; i < GSF_END; i++) {
00121 this->spritesets[i].clear();
00122 }
00123
00124 memset(this->spritegroups, 0, sizeof(this->spritegroups));
00125 }
00126
00135 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
00136 {
00137 assert(feature < GSF_END);
00138 for (uint i = 0; i < numsets; i++) {
00139 SpriteSet &set = this->spritesets[feature][first_set + i];
00140 set.sprite = first_sprite + i * numents;
00141 set.num_sprites = numents;
00142 }
00143 }
00144
00151 bool HasValidSpriteSets(byte feature) const
00152 {
00153 assert(feature < GSF_END);
00154 return !this->spritesets[feature].empty();
00155 }
00156
00164 bool IsValidSpriteSet(byte feature, uint set) const
00165 {
00166 assert(feature < GSF_END);
00167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
00168 }
00169
00176 SpriteID GetSprite(byte feature, uint set) const
00177 {
00178 assert(IsValidSpriteSet(feature, set));
00179 return this->spritesets[feature].find(set)->second.sprite;
00180 }
00181
00188 uint GetNumEnts(byte feature, uint set) const
00189 {
00190 assert(IsValidSpriteSet(feature, set));
00191 return this->spritesets[feature].find(set)->second.num_sprites;
00192 }
00193 };
00194
00195 static GrfProcessingState _cur;
00196
00197
00198 class OTTDByteReaderSignal { };
00199
00201 class ByteReader {
00202 protected:
00203 byte *data;
00204 byte *end;
00205
00206 public:
00207 ByteReader(byte *data, byte *end) : data(data), end(end) { }
00208
00209 inline byte ReadByte()
00210 {
00211 if (data < end) return *(data)++;
00212 throw OTTDByteReaderSignal();
00213 }
00214
00215 uint16 ReadWord()
00216 {
00217 uint16 val = ReadByte();
00218 return val | (ReadByte() << 8);
00219 }
00220
00221 uint16 ReadExtendedByte()
00222 {
00223 uint16 val = ReadByte();
00224 return val == 0xFF ? ReadWord() : val;
00225 }
00226
00227 uint32 ReadDWord()
00228 {
00229 uint32 val = ReadWord();
00230 return val | (ReadWord() << 16);
00231 }
00232
00233 uint32 ReadVarSize(byte size)
00234 {
00235 switch (size) {
00236 case 1: return ReadByte();
00237 case 2: return ReadWord();
00238 case 4: return ReadDWord();
00239 default:
00240 NOT_REACHED();
00241 return 0;
00242 }
00243 }
00244
00245 const char *ReadString()
00246 {
00247 char *string = reinterpret_cast<char *>(data);
00248 size_t string_length = ttd_strnlen(string, Remaining());
00249
00250 if (string_length == Remaining()) {
00251
00252 string[string_length - 1] = '\0';
00253 grfmsg(7, "String was not terminated with a zero byte.");
00254 } else {
00255
00256 string_length++;
00257 }
00258 Skip(string_length);
00259
00260 return string;
00261 }
00262
00263 inline size_t Remaining() const
00264 {
00265 return end - data;
00266 }
00267
00268 inline bool HasData(size_t count = 1) const
00269 {
00270 return data + count <= end;
00271 }
00272
00273 inline byte *Data()
00274 {
00275 return data;
00276 }
00277
00278 inline void Skip(size_t len)
00279 {
00280 data += len;
00281
00282
00283 if (data > end) throw OTTDByteReaderSignal();
00284 }
00285 };
00286
00287 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
00288
00289 static const uint MAX_STATIONS = 256;
00290
00292 struct GRFTempEngineData {
00293 uint16 cargo_allowed;
00294 uint16 cargo_disallowed;
00295 RailTypeLabel railtypelabel;
00296 const GRFFile *refitmask_grf;
00297 bool refitmask_valid;
00298 bool prop27_set;
00299 uint8 rv_max_speed;
00300 uint32 ctt_include_mask;
00301 uint32 ctt_exclude_mask;
00302 };
00303
00304 static GRFTempEngineData *_gted;
00305
00310 static uint32 _grm_engines[256];
00311
00313 static uint32 _grm_cargoes[NUM_CARGO * 2];
00314
00315 struct GRFLocation {
00316 uint32 grfid;
00317 uint32 nfoline;
00318
00319 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
00320
00321 bool operator<(const GRFLocation &other) const
00322 {
00323 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
00324 }
00325
00326 bool operator == (const GRFLocation &other) const
00327 {
00328 return this->grfid == other.grfid && this->nfoline == other.nfoline;
00329 }
00330 };
00331
00332 static std::map<GRFLocation, SpriteID> _grm_sprites;
00333 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
00334 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
00335
00346 void CDECL grfmsg(int severity, const char *str, ...)
00347 {
00348 char buf[1024];
00349 va_list va;
00350
00351 va_start(va, str);
00352 vsnprintf(buf, sizeof(buf), str, va);
00353 va_end(va);
00354
00355 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
00356 }
00357
00363 static GRFFile *GetFileByGRFID(uint32 grfid)
00364 {
00365 const GRFFile * const *end = _grf_files.End();
00366 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00367 if ((*file)->grfid == grfid) return *file;
00368 }
00369 return NULL;
00370 }
00371
00377 static GRFFile *GetFileByFilename(const char *filename)
00378 {
00379 const GRFFile * const *end = _grf_files.End();
00380 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00381 if (strcmp((*file)->filename, filename) == 0) return *file;
00382 }
00383 return NULL;
00384 }
00385
00387 static void ClearTemporaryNewGRFData(GRFFile *gf)
00388 {
00389
00390 for (GRFLabel *l = gf->label; l != NULL;) {
00391 GRFLabel *l2 = l->next;
00392 free(l);
00393 l = l2;
00394 }
00395 gf->label = NULL;
00396 }
00397
00404 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
00405 {
00406 GRFFile *file;
00407 if (config != NULL) {
00408 file = GetFileByGRFID(config->ident.grfid);
00409 } else {
00410 config = _cur.grfconfig;
00411 file = _cur.grffile;
00412 }
00413
00414 config->status = GCS_DISABLED;
00415 if (file != NULL) ClearTemporaryNewGRFData(file);
00416 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
00417
00418 if (message != STR_NULL) {
00419 delete config->error;
00420 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
00421 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
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 if (prop == 0x15) {
02523 buf->ReadByte();
02524 } else {
02525 while (buf->ReadByte() != 0) {
02526 buf->ReadString();
02527 }
02528 }
02529 break;
02530 }
02531
02532 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
02533
02534 if (prop == 0x15) {
02535 uint plural_form = buf->ReadByte();
02536 if (plural_form >= LANGUAGE_MAX_PLURAL) {
02537 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
02538 } else {
02539 _cur.grffile->language_map[curidx].plural_form = plural_form;
02540 }
02541 break;
02542 }
02543
02544 byte newgrf_id = buf->ReadByte();
02545 while (newgrf_id != 0) {
02546 const char *name = buf->ReadString();
02547
02548
02549
02550
02551
02552 WChar c;
02553 size_t len = Utf8Decode(&c, name);
02554 if (c == NFO_UTF8_IDENTIFIER) name += len;
02555
02556 LanguageMap::Mapping map;
02557 map.newgrf_id = newgrf_id;
02558 if (prop == 0x13) {
02559 map.openttd_id = lang->GetGenderIndex(name);
02560 if (map.openttd_id >= MAX_NUM_GENDERS) {
02561 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
02562 } else {
02563 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
02564 }
02565 } else {
02566 map.openttd_id = lang->GetCaseIndex(name);
02567 if (map.openttd_id >= MAX_NUM_CASES) {
02568 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
02569 } else {
02570 *_cur.grffile->language_map[curidx].case_map.Append() = map;
02571 }
02572 }
02573 newgrf_id = buf->ReadByte();
02574 }
02575 break;
02576 }
02577
02578 default:
02579 ret = CIR_UNKNOWN;
02580 break;
02581 }
02582 }
02583
02584 return ret;
02585 }
02586
02587 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
02588 {
02589 ChangeInfoResult ret = CIR_SUCCESS;
02590
02591 for (int i = 0; i < numinfo; i++) {
02592 switch (prop) {
02593 case 0x08:
02594 case 0x15:
02595 buf->ReadByte();
02596 break;
02597
02598 case 0x09: {
02599 if (i == 0) {
02600 if (gvid != 0) {
02601 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
02602 return CIR_INVALID_ID;
02603 }
02604
02605 free(_cur.grffile->cargo_list);
02606 _cur.grffile->cargo_max = numinfo;
02607 _cur.grffile->cargo_list = MallocT<CargoLabel>(numinfo);
02608 }
02609
02610 CargoLabel cl = buf->ReadDWord();
02611 _cur.grffile->cargo_list[i] = BSWAP32(cl);
02612 break;
02613 }
02614
02615 case 0x0A:
02616 case 0x0C:
02617 case 0x0F:
02618 buf->ReadWord();
02619 break;
02620
02621 case 0x0B:
02622 case 0x0D:
02623 case 0x0E:
02624 buf->ReadDWord();
02625 break;
02626
02627 case 0x10:
02628 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
02629 break;
02630
02631 case 0x11: {
02632 uint32 s = buf->ReadDWord();
02633 uint32 t = buf->ReadDWord();
02634 SetNewGRFOverride(s, t);
02635 break;
02636 }
02637
02638 case 0x12: {
02639 if (i == 0) {
02640 if (gvid != 0) {
02641 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
02642 return CIR_INVALID_ID;
02643 }
02644
02645 free(_cur.grffile->railtype_list);
02646 _cur.grffile->railtype_max = numinfo;
02647 _cur.grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
02648 }
02649
02650 RailTypeLabel rtl = buf->ReadDWord();
02651 _cur.grffile->railtype_list[i] = BSWAP32(rtl);
02652 break;
02653 }
02654
02655 case 0x13:
02656 case 0x14:
02657 while (buf->ReadByte() != 0) {
02658 buf->ReadString();
02659 }
02660 break;
02661
02662 default:
02663 ret = CIR_UNKNOWN;
02664 break;
02665 }
02666 }
02667
02668 return ret;
02669 }
02670
02671
02680 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
02681 {
02682 ChangeInfoResult ret = CIR_SUCCESS;
02683
02684 if (cid + numinfo > NUM_CARGO) {
02685 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
02686 return CIR_INVALID_ID;
02687 }
02688
02689 for (int i = 0; i < numinfo; i++) {
02690 CargoSpec *cs = CargoSpec::Get(cid + i);
02691
02692 switch (prop) {
02693 case 0x08:
02694 cs->bitnum = buf->ReadByte();
02695 if (cs->IsValid()) {
02696 cs->grffile = _cur.grffile;
02697 SetBit(_cargo_mask, cid + i);
02698 } else {
02699 ClrBit(_cargo_mask, cid + i);
02700 }
02701 break;
02702
02703 case 0x09:
02704 cs->name = buf->ReadWord();
02705 _string_to_grf_mapping[&cs->name] = _cur.grffile->grfid;
02706 break;
02707
02708 case 0x0A:
02709 cs->name_single = buf->ReadWord();
02710 _string_to_grf_mapping[&cs->name_single] = _cur.grffile->grfid;
02711 break;
02712
02713 case 0x0B:
02714 case 0x1B:
02715
02716
02717
02718 cs->units_volume = buf->ReadWord();
02719 _string_to_grf_mapping[&cs->units_volume] = _cur.grffile->grfid;
02720 break;
02721
02722 case 0x0C:
02723 case 0x1C:
02724
02725
02726
02727 cs->quantifier = buf->ReadWord();
02728 _string_to_grf_mapping[&cs->quantifier] = _cur.grffile->grfid;
02729 break;
02730
02731 case 0x0D:
02732 cs->abbrev = buf->ReadWord();
02733 _string_to_grf_mapping[&cs->abbrev] = _cur.grffile->grfid;
02734 break;
02735
02736 case 0x0E:
02737 cs->sprite = buf->ReadWord();
02738 break;
02739
02740 case 0x0F:
02741 cs->weight = buf->ReadByte();
02742 break;
02743
02744 case 0x10:
02745 cs->transit_days[0] = buf->ReadByte();
02746 break;
02747
02748 case 0x11:
02749 cs->transit_days[1] = buf->ReadByte();
02750 break;
02751
02752 case 0x12:
02753 cs->initial_payment = buf->ReadDWord();
02754 break;
02755
02756 case 0x13:
02757 cs->rating_colour = buf->ReadByte();
02758 break;
02759
02760 case 0x14:
02761 cs->legend_colour = buf->ReadByte();
02762 break;
02763
02764 case 0x15:
02765 cs->is_freight = (buf->ReadByte() != 0);
02766 break;
02767
02768 case 0x16:
02769 cs->classes = buf->ReadWord();
02770 break;
02771
02772 case 0x17:
02773 cs->label = buf->ReadDWord();
02774 cs->label = BSWAP32(cs->label);
02775 break;
02776
02777 case 0x18: {
02778 uint8 substitute_type = buf->ReadByte();
02779
02780 switch (substitute_type) {
02781 case 0x00: cs->town_effect = TE_PASSENGERS; break;
02782 case 0x02: cs->town_effect = TE_MAIL; break;
02783 case 0x05: cs->town_effect = TE_GOODS; break;
02784 case 0x09: cs->town_effect = TE_WATER; break;
02785 case 0x0B: cs->town_effect = TE_FOOD; break;
02786 default:
02787 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
02788 case 0xFF: cs->town_effect = TE_NONE; break;
02789 }
02790 break;
02791 }
02792
02793 case 0x19:
02794 cs->multipliertowngrowth = buf->ReadWord();
02795 break;
02796
02797 case 0x1A:
02798 cs->callback_mask = buf->ReadByte();
02799 break;
02800
02801 case 0x1D:
02802 cs->multiplier = max<uint16>(1u, buf->ReadWord());
02803 break;
02804
02805 default:
02806 ret = CIR_UNKNOWN;
02807 break;
02808 }
02809 }
02810
02811 return ret;
02812 }
02813
02814
02823 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02824 {
02825 ChangeInfoResult ret = CIR_SUCCESS;
02826
02827 if (_cur.grffile->sound_offset == 0) {
02828 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02829 return CIR_INVALID_ID;
02830 }
02831
02832 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
02833 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
02834 return CIR_INVALID_ID;
02835 }
02836
02837 for (int i = 0; i < numinfo; i++) {
02838 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
02839
02840 switch (prop) {
02841 case 0x08:
02842 sound->volume = buf->ReadByte();
02843 break;
02844
02845 case 0x09:
02846 sound->priority = buf->ReadByte();
02847 break;
02848
02849 case 0x0A: {
02850 SoundID orig_sound = buf->ReadByte();
02851
02852 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02853 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02854 } else {
02855 SoundEntry *old_sound = GetSound(orig_sound);
02856
02857
02858 *old_sound = *sound;
02859 }
02860 break;
02861 }
02862
02863 default:
02864 ret = CIR_UNKNOWN;
02865 break;
02866 }
02867 }
02868
02869 return ret;
02870 }
02871
02878 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
02879 {
02880 ChangeInfoResult ret = CIR_SUCCESS;
02881
02882 switch (prop) {
02883 case 0x09:
02884 case 0x0D:
02885 case 0x0E:
02886 case 0x10:
02887 case 0x11:
02888 case 0x12:
02889 buf->ReadByte();
02890 break;
02891
02892 case 0x0A:
02893 case 0x0B:
02894 case 0x0C:
02895 case 0x0F:
02896 buf->ReadWord();
02897 break;
02898
02899 default:
02900 ret = CIR_UNKNOWN;
02901 break;
02902 }
02903 return ret;
02904 }
02905
02914 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02915 {
02916 ChangeInfoResult ret = CIR_SUCCESS;
02917
02918 if (indtid + numinfo > NUM_INDUSTRYTILES) {
02919 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02920 return CIR_INVALID_ID;
02921 }
02922
02923
02924 if (_cur.grffile->indtspec == NULL) {
02925 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02926 }
02927
02928 for (int i = 0; i < numinfo; i++) {
02929 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
02930
02931 if (prop != 0x08 && tsp == NULL) {
02932 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
02933 if (cir > ret) ret = cir;
02934 continue;
02935 }
02936
02937 switch (prop) {
02938 case 0x08: {
02939 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
02940 byte subs_id = buf->ReadByte();
02941
02942 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
02943
02944 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
02945 continue;
02946 }
02947
02948
02949 if (*tilespec == NULL) {
02950 *tilespec = CallocT<IndustryTileSpec>(1);
02951 tsp = *tilespec;
02952
02953 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
02954 tsp->enabled = true;
02955
02956
02957
02958
02959 tsp->anim_production = INDUSTRYTILE_NOANIM;
02960 tsp->anim_next = INDUSTRYTILE_NOANIM;
02961
02962 tsp->grf_prop.local_id = indtid + i;
02963 tsp->grf_prop.subst_id = subs_id;
02964 tsp->grf_prop.grffile = _cur.grffile;
02965 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id);
02966 }
02967 break;
02968 }
02969
02970 case 0x09: {
02971 byte ovrid = buf->ReadByte();
02972
02973
02974 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
02975 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
02976 continue;
02977 }
02978
02979 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
02980 break;
02981 }
02982
02983 case 0x0A:
02984 case 0x0B:
02985 case 0x0C: {
02986 uint16 acctp = buf->ReadWord();
02987 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
02988 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
02989 break;
02990 }
02991
02992 case 0x0D:
02993 tsp->slopes_refused = (Slope)buf->ReadByte();
02994 break;
02995
02996 case 0x0E:
02997 tsp->callback_mask = buf->ReadByte();
02998 break;
02999
03000 case 0x0F:
03001 tsp->animation.frames = buf->ReadByte();
03002 tsp->animation.status = buf->ReadByte();
03003 break;
03004
03005 case 0x10:
03006 tsp->animation.speed = buf->ReadByte();
03007 break;
03008
03009 case 0x11:
03010 tsp->animation.triggers = buf->ReadByte();
03011 break;
03012
03013 case 0x12:
03014 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
03015 break;
03016
03017 default:
03018 ret = CIR_UNKNOWN;
03019 break;
03020 }
03021 }
03022
03023 return ret;
03024 }
03025
03032 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
03033 {
03034 ChangeInfoResult ret = CIR_SUCCESS;
03035
03036 switch (prop) {
03037 case 0x09:
03038 case 0x0B:
03039 case 0x0F:
03040 case 0x12:
03041 case 0x13:
03042 case 0x14:
03043 case 0x17:
03044 case 0x18:
03045 case 0x19:
03046 case 0x21:
03047 case 0x22:
03048 buf->ReadByte();
03049 break;
03050
03051 case 0x0C:
03052 case 0x0D:
03053 case 0x0E:
03054 case 0x10:
03055 case 0x1B:
03056 case 0x1F:
03057 case 0x24:
03058 buf->ReadWord();
03059 break;
03060
03061 case 0x11:
03062 case 0x1A:
03063 case 0x1C:
03064 case 0x1D:
03065 case 0x1E:
03066 case 0x20:
03067 case 0x23:
03068 buf->ReadDWord();
03069 break;
03070
03071 case 0x0A: {
03072 byte num_table = buf->ReadByte();
03073 for (byte j = 0; j < num_table; j++) {
03074 for (uint k = 0;; k++) {
03075 byte x = buf->ReadByte();
03076 if (x == 0xFE && k == 0) {
03077 buf->ReadByte();
03078 buf->ReadByte();
03079 break;
03080 }
03081
03082 byte y = buf->ReadByte();
03083 if (x == 0 && y == 0x80) break;
03084
03085 byte gfx = buf->ReadByte();
03086 if (gfx == 0xFE) buf->ReadWord();
03087 }
03088 }
03089 break;
03090 }
03091
03092 case 0x16:
03093 for (byte j = 0; j < 3; j++) buf->ReadByte();
03094 break;
03095
03096 case 0x15: {
03097 byte number_of_sounds = buf->ReadByte();
03098 for (uint8 j = 0; j < number_of_sounds; j++) {
03099 buf->ReadByte();
03100 }
03101 break;
03102 }
03103
03104 default:
03105 ret = CIR_UNKNOWN;
03106 break;
03107 }
03108 return ret;
03109 }
03110
03117 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
03118 {
03119 for (int i = 0; i < size - 1; i++) {
03120 for (int j = i + 1; j < size; j++) {
03121 if (layout[i].ti.x == layout[j].ti.x &&
03122 layout[i].ti.y == layout[j].ti.y) {
03123 return false;
03124 }
03125 }
03126 }
03127 return true;
03128 }
03129
03131 static void CleanIndustryTileTable(IndustrySpec *ind)
03132 {
03133 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
03134 for (int j = 0; j < ind->num_table; j++) {
03135
03136 free(ind->table[j]);
03137 }
03138
03139 free(ind->table);
03140 ind->table = NULL;
03141 }
03142 }
03143
03152 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
03153 {
03154 ChangeInfoResult ret = CIR_SUCCESS;
03155
03156 if (indid + numinfo > NUM_INDUSTRYTYPES) {
03157 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
03158 return CIR_INVALID_ID;
03159 }
03160
03161 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
03162
03163
03164 if (_cur.grffile->industryspec == NULL) {
03165 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
03166 }
03167
03168 for (int i = 0; i < numinfo; i++) {
03169 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
03170
03171 if (prop != 0x08 && indsp == NULL) {
03172 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
03173 if (cir > ret) ret = cir;
03174 continue;
03175 }
03176
03177 switch (prop) {
03178 case 0x08: {
03179 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
03180 byte subs_id = buf->ReadByte();
03181
03182 if (subs_id == 0xFF) {
03183
03184
03185 _industry_specs[indid + i].enabled = false;
03186 continue;
03187 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
03188
03189 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
03190 continue;
03191 }
03192
03193
03194
03195
03196 if (*indspec == NULL) {
03197 *indspec = CallocT<IndustrySpec>(1);
03198 indsp = *indspec;
03199
03200 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
03201 indsp->enabled = true;
03202 indsp->grf_prop.local_id = indid + i;
03203 indsp->grf_prop.subst_id = subs_id;
03204 indsp->grf_prop.grffile = _cur.grffile;
03205
03206
03207 indsp->check_proc = CHECK_NOTHING;
03208 }
03209 break;
03210 }
03211
03212 case 0x09: {
03213 byte ovrid = buf->ReadByte();
03214
03215
03216 if (ovrid >= NEW_INDUSTRYOFFSET) {
03217 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
03218 continue;
03219 }
03220 indsp->grf_prop.override = ovrid;
03221 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
03222 break;
03223 }
03224
03225 case 0x0A: {
03226 byte new_num_layouts = buf->ReadByte();
03227
03228
03229
03230
03231
03232 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
03233 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts);
03234 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles);
03235 uint size;
03236 const IndustryTileTable *copy_from;
03237
03238 try {
03239 for (byte j = 0; j < new_num_layouts; j++) {
03240 for (uint k = 0;; k++) {
03241 if (k >= def_num_tiles) {
03242 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
03243
03244 def_num_tiles *= 2;
03245 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
03246 }
03247
03248 itt[k].ti.x = buf->ReadByte();
03249
03250 if (itt[k].ti.x == 0xFE && k == 0) {
03251
03252 IndustryType type = buf->ReadByte();
03253 byte laynbr = buf->ReadByte();
03254
03255 copy_from = _origin_industry_specs[type].table[laynbr];
03256 for (size = 1;; size++) {
03257 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
03258 }
03259 break;
03260 }
03261
03262 itt[k].ti.y = buf->ReadByte();
03263
03264 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
03265
03266
03267 itt[k].ti.x = -0x80;
03268 itt[k].ti.y = 0;
03269 itt[k].gfx = 0;
03270
03271 size = k + 1;
03272 copy_from = itt;
03273 break;
03274 }
03275
03276 itt[k].gfx = buf->ReadByte();
03277
03278 if (itt[k].gfx == 0xFE) {
03279
03280 int local_tile_id = buf->ReadWord();
03281
03282
03283 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
03284
03285 if (tempid == INVALID_INDUSTRYTILE) {
03286 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
03287 } else {
03288
03289 itt[k].gfx = tempid;
03290 size = k + 1;
03291 copy_from = itt;
03292 }
03293 } else if (itt[k].gfx == 0xFF) {
03294 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
03295 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
03296 }
03297 }
03298
03299 if (!ValidateIndustryLayout(copy_from, size)) {
03300
03301 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
03302 new_num_layouts--;
03303 j--;
03304 } else {
03305 tile_table[j] = CallocT<IndustryTileTable>(size);
03306 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03307 }
03308 }
03309 } catch (...) {
03310 for (int i = 0; i < new_num_layouts; i++) {
03311 free(tile_table[i]);
03312 }
03313 free(tile_table);
03314 free(itt);
03315 throw;
03316 }
03317
03318
03319 CleanIndustryTileTable(indsp);
03320
03321 indsp->num_table = new_num_layouts;
03322 indsp->table = tile_table;
03323 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
03324 free(itt);
03325 break;
03326 }
03327
03328 case 0x0B:
03329 indsp->life_type = (IndustryLifeType)buf->ReadByte();
03330 break;
03331
03332 case 0x0C:
03333 indsp->closure_text = buf->ReadWord();
03334 _string_to_grf_mapping[&indsp->closure_text] = _cur.grffile->grfid;
03335 break;
03336
03337 case 0x0D:
03338 indsp->production_up_text = buf->ReadWord();
03339 _string_to_grf_mapping[&indsp->production_up_text] = _cur.grffile->grfid;
03340 break;
03341
03342 case 0x0E:
03343 indsp->production_down_text = buf->ReadWord();
03344 _string_to_grf_mapping[&indsp->production_down_text] = _cur.grffile->grfid;
03345 break;
03346
03347 case 0x0F:
03348 indsp->cost_multiplier = buf->ReadByte();
03349 break;
03350
03351 case 0x10:
03352 for (byte j = 0; j < 2; j++) {
03353 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
03354 }
03355 break;
03356
03357 case 0x11:
03358 for (byte j = 0; j < 3; j++) {
03359 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
03360 }
03361 buf->ReadByte();
03362 break;
03363
03364 case 0x12:
03365 case 0x13:
03366 indsp->production_rate[prop - 0x12] = buf->ReadByte();
03367 break;
03368
03369 case 0x14:
03370 indsp->minimal_cargo = buf->ReadByte();
03371 break;
03372
03373 case 0x15: {
03374 indsp->number_of_sounds = buf->ReadByte();
03375 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
03376
03377 try {
03378 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
03379 sounds[j] = buf->ReadByte();
03380 }
03381 } catch (...) {
03382 free(sounds);
03383 throw;
03384 }
03385
03386 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
03387 free(indsp->random_sounds);
03388 }
03389 indsp->random_sounds = sounds;
03390 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
03391 break;
03392 }
03393
03394 case 0x16:
03395 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
03396 break;
03397
03398 case 0x17:
03399 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
03400 break;
03401
03402 case 0x18:
03403 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
03404 break;
03405
03406 case 0x19:
03407 indsp->map_colour = buf->ReadByte();
03408 break;
03409
03410 case 0x1A:
03411 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
03412 break;
03413
03414 case 0x1B:
03415 indsp->new_industry_text = buf->ReadWord();
03416 _string_to_grf_mapping[&indsp->new_industry_text] = _cur.grffile->grfid;
03417 break;
03418
03419 case 0x1C:
03420 case 0x1D:
03421 case 0x1E: {
03422 uint32 multiples = buf->ReadDWord();
03423 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
03424 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
03425 break;
03426 }
03427
03428 case 0x1F:
03429 indsp->name = buf->ReadWord();
03430 _string_to_grf_mapping[&indsp->name] = _cur.grffile->grfid;
03431 break;
03432
03433 case 0x20:
03434 indsp->prospecting_chance = buf->ReadDWord();
03435 break;
03436
03437 case 0x21:
03438 case 0x22: {
03439 byte aflag = buf->ReadByte();
03440 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
03441 break;
03442 }
03443
03444 case 0x23:
03445 indsp->removal_cost_multiplier = buf->ReadDWord();
03446 break;
03447
03448 case 0x24:
03449 indsp->station_name = buf->ReadWord();
03450 if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur.grffile->grfid;
03451 break;
03452
03453 default:
03454 ret = CIR_UNKNOWN;
03455 break;
03456 }
03457 }
03458
03459 return ret;
03460 }
03461
03467 static void DuplicateTileTable(AirportSpec *as)
03468 {
03469 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
03470 for (int i = 0; i < as->num_table; i++) {
03471 uint num_tiles = 1;
03472 const AirportTileTable *it = as->table[0];
03473 do {
03474 num_tiles++;
03475 } while ((++it)->ti.x != -0x80);
03476 table_list[i] = MallocT<AirportTileTable>(num_tiles);
03477 MemCpyT(table_list[i], as->table[i], num_tiles);
03478 }
03479 as->table = table_list;
03480 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
03481 MemCpyT(depot_table, as->depot_table, as->nof_depots);
03482 as->depot_table = depot_table;
03483 }
03484
03493 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
03494 {
03495 ChangeInfoResult ret = CIR_SUCCESS;
03496
03497 if (airport + numinfo > NUM_AIRPORTS) {
03498 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS);
03499 return CIR_INVALID_ID;
03500 }
03501
03502 grfmsg(1, "AirportChangeInfo: newid %u", airport);
03503
03504
03505 if (_cur.grffile->airportspec == NULL) {
03506 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS);
03507 }
03508
03509 for (int i = 0; i < numinfo; i++) {
03510 AirportSpec *as = _cur.grffile->airportspec[airport + i];
03511
03512 if (as == NULL && prop != 0x08 && prop != 0x09) {
03513 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
03514 return CIR_INVALID_ID;
03515 }
03516
03517 switch (prop) {
03518 case 0x08: {
03519 byte subs_id = buf->ReadByte();
03520
03521 if (subs_id == 0xFF) {
03522
03523
03524 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
03525 continue;
03526 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
03527
03528 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
03529 continue;
03530 }
03531
03532 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
03533
03534
03535
03536 if (*spec == NULL) {
03537 *spec = MallocT<AirportSpec>(1);
03538 as = *spec;
03539
03540 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
03541 as->enabled = true;
03542 as->grf_prop.local_id = airport + i;
03543 as->grf_prop.subst_id = subs_id;
03544 as->grf_prop.grffile = _cur.grffile;
03545
03546 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
03547
03548 DuplicateTileTable(as);
03549 }
03550 break;
03551 }
03552
03553 case 0x0A: {
03554 as->num_table = buf->ReadByte();
03555 as->rotation = MallocT<Direction>(as->num_table);
03556 uint32 defsize = buf->ReadDWord();
03557 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table);
03558 AirportTileTable *att = CallocT<AirportTileTable>(defsize);
03559 int size;
03560 const AirportTileTable *copy_from;
03561 try {
03562 for (byte j = 0; j < as->num_table; j++) {
03563 as->rotation[j] = (Direction)buf->ReadByte();
03564 for (int k = 0;; k++) {
03565 att[k].ti.x = buf->ReadByte();
03566 att[k].ti.y = buf->ReadByte();
03567
03568 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
03569
03570
03571 att[k].ti.x = -0x80;
03572 att[k].ti.y = 0;
03573 att[k].gfx = 0;
03574
03575 size = k + 1;
03576 copy_from = att;
03577 break;
03578 }
03579
03580 att[k].gfx = buf->ReadByte();
03581
03582 if (att[k].gfx == 0xFE) {
03583
03584 int local_tile_id = buf->ReadWord();
03585
03586
03587 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
03588
03589 if (tempid == INVALID_AIRPORTTILE) {
03590 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
03591 } else {
03592
03593 att[k].gfx = tempid;
03594 size = k + 1;
03595 copy_from = att;
03596 }
03597 } else if (att[k].gfx == 0xFF) {
03598 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
03599 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
03600 }
03601
03602 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
03603 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
03604 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
03605 } else {
03606 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
03607 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
03608 }
03609 }
03610 tile_table[j] = CallocT<AirportTileTable>(size);
03611 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03612 }
03613
03614 as->table = tile_table;
03615 free(att);
03616 } catch (...) {
03617 for (int i = 0; i < as->num_table; i++) {
03618 free(tile_table[i]);
03619 }
03620 free(tile_table);
03621 free(att);
03622 throw;
03623 }
03624 break;
03625 }
03626
03627 case 0x0C:
03628 as->min_year = buf->ReadWord();
03629 as->max_year = buf->ReadWord();
03630 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
03631 break;
03632
03633 case 0x0D:
03634 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
03635 break;
03636
03637 case 0x0E:
03638 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
03639 break;
03640
03641 case 0x0F:
03642 as->noise_level = buf->ReadByte();
03643 break;
03644
03645 case 0x10:
03646 as->name = buf->ReadWord();
03647 _string_to_grf_mapping[&as->name] = _cur.grffile->grfid;
03648 break;
03649
03650 case 0x11:
03651 as->maintenance_cost = buf->ReadWord();
03652 break;
03653
03654 default:
03655 ret = CIR_UNKNOWN;
03656 break;
03657 }
03658 }
03659
03660 return ret;
03661 }
03662
03669 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
03670 {
03671 ChangeInfoResult ret = CIR_SUCCESS;
03672
03673 switch (prop) {
03674 case 0x0B:
03675 case 0x0C:
03676 case 0x0D:
03677 case 0x12:
03678 case 0x14:
03679 case 0x16:
03680 case 0x17:
03681 buf->ReadByte();
03682
03683 case 0x09:
03684 case 0x0A:
03685 case 0x10:
03686 case 0x11:
03687 case 0x13:
03688 case 0x15:
03689 buf->ReadWord();
03690 break;
03691
03692 case 0x08:
03693 case 0x0E:
03694 case 0x0F:
03695 buf->ReadDWord();
03696 break;
03697
03698 default:
03699 ret = CIR_UNKNOWN;
03700 break;
03701 }
03702
03703 return ret;
03704 }
03705
03714 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03715 {
03716 ChangeInfoResult ret = CIR_SUCCESS;
03717
03718 if (id + numinfo > NUM_OBJECTS) {
03719 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS);
03720 return CIR_INVALID_ID;
03721 }
03722
03723
03724 if (_cur.grffile->objectspec == NULL) {
03725 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS);
03726 }
03727
03728 for (int i = 0; i < numinfo; i++) {
03729 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
03730
03731 if (prop != 0x08 && spec == NULL) {
03732
03733 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
03734 if (cir > ret) ret = cir;
03735 continue;
03736 }
03737
03738 switch (prop) {
03739 case 0x08: {
03740 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
03741
03742
03743 if (*ospec == NULL) {
03744 *ospec = CallocT<ObjectSpec>(1);
03745 (*ospec)->views = 1;
03746 }
03747
03748
03749 uint32 classid = buf->ReadDWord();
03750 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
03751 (*ospec)->enabled = true;
03752 break;
03753 }
03754
03755 case 0x09: {
03756 StringID class_name = buf->ReadWord();
03757 ObjectClass::SetName(spec->cls_id, class_name);
03758 _string_to_grf_mapping[&ObjectClass::classes[spec->cls_id].name] = _cur.grffile->grfid;
03759 break;
03760 }
03761
03762 case 0x0A:
03763 spec->name = buf->ReadWord();
03764 _string_to_grf_mapping[&spec->name] = _cur.grffile->grfid;
03765 break;
03766
03767 case 0x0B:
03768 spec->climate = buf->ReadByte();
03769 break;
03770
03771 case 0x0C:
03772 spec->size = buf->ReadByte();
03773 break;
03774
03775 case 0x0D:
03776 spec->build_cost_multiplier = buf->ReadByte();
03777 spec->clear_cost_multiplier = spec->build_cost_multiplier;
03778 break;
03779
03780 case 0x0E:
03781 spec->introduction_date = buf->ReadDWord();
03782 break;
03783
03784 case 0x0F:
03785 spec->end_of_life_date = buf->ReadDWord();
03786 break;
03787
03788 case 0x10:
03789 spec->flags = (ObjectFlags)buf->ReadWord();
03790 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
03791 break;
03792
03793 case 0x11:
03794 spec->animation.frames = buf->ReadByte();
03795 spec->animation.status = buf->ReadByte();
03796 break;
03797
03798 case 0x12:
03799 spec->animation.speed = buf->ReadByte();
03800 break;
03801
03802 case 0x13:
03803 spec->animation.triggers = buf->ReadWord();
03804 break;
03805
03806 case 0x14:
03807 spec->clear_cost_multiplier = buf->ReadByte();
03808 break;
03809
03810 case 0x15:
03811 spec->callback_mask = buf->ReadWord();
03812 break;
03813
03814 case 0x16:
03815 spec->height = buf->ReadByte();
03816 break;
03817
03818 case 0x17:
03819 spec->views = buf->ReadByte();
03820 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
03821 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
03822 spec->views = 1;
03823 }
03824 break;
03825
03826 default:
03827 ret = CIR_UNKNOWN;
03828 break;
03829 }
03830 }
03831
03832 return ret;
03833 }
03834
03843 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03844 {
03845 ChangeInfoResult ret = CIR_SUCCESS;
03846
03847 extern RailtypeInfo _railtypes[RAILTYPE_END];
03848
03849 if (id + numinfo > RAILTYPE_END) {
03850 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03851 return CIR_INVALID_ID;
03852 }
03853
03854 for (int i = 0; i < numinfo; i++) {
03855 RailType rt = _cur.grffile->railtype_map[id + i];
03856 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
03857
03858 RailtypeInfo *rti = &_railtypes[rt];
03859
03860 switch (prop) {
03861 case 0x08:
03862
03863 buf->ReadDWord();
03864 break;
03865
03866 case 0x09:
03867 rti->strings.toolbar_caption = buf->ReadWord();
03868 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur.grffile->grfid;
03869 if (_cur.grffile->grf_version < 8) {
03870 rti->strings.name = rti->strings.toolbar_caption;
03871 _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
03872 }
03873 break;
03874
03875 case 0x0A:
03876 rti->strings.menu_text = buf->ReadWord();
03877 _string_to_grf_mapping[&rti->strings.menu_text] = _cur.grffile->grfid;
03878 break;
03879
03880 case 0x0B:
03881 rti->strings.build_caption = buf->ReadWord();
03882 _string_to_grf_mapping[&rti->strings.build_caption] = _cur.grffile->grfid;
03883 break;
03884
03885 case 0x0C:
03886 rti->strings.replace_text = buf->ReadWord();
03887 _string_to_grf_mapping[&rti->strings.replace_text] = _cur.grffile->grfid;
03888 break;
03889
03890 case 0x0D:
03891 rti->strings.new_loco = buf->ReadWord();
03892 _string_to_grf_mapping[&rti->strings.new_loco] = _cur.grffile->grfid;
03893 break;
03894
03895 case 0x0E:
03896 case 0x0F:
03897 case 0x18:
03898 case 0x19:
03899 {
03900
03901
03902
03903 int n = buf->ReadByte();
03904 for (int j = 0; j != n; j++) {
03905 RailTypeLabel label = buf->ReadDWord();
03906 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
03907 if (rt != INVALID_RAILTYPE) {
03908 switch (prop) {
03909 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
03910 case 0x0F: SetBit(rti->powered_railtypes, rt); break;
03911 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
03912 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
03913 }
03914 }
03915 }
03916 break;
03917 }
03918
03919 case 0x10:
03920 rti->flags = (RailTypeFlags)buf->ReadByte();
03921 break;
03922
03923 case 0x11:
03924 rti->curve_speed = buf->ReadByte();
03925 break;
03926
03927 case 0x12:
03928 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
03929 break;
03930
03931 case 0x13:
03932 rti->cost_multiplier = buf->ReadWord();
03933 break;
03934
03935 case 0x14:
03936 rti->max_speed = buf->ReadWord();
03937 break;
03938
03939 case 0x15:
03940 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
03941 break;
03942
03943 case 0x16:
03944 rti->map_colour = buf->ReadByte();
03945 break;
03946
03947 case 0x17:
03948 rti->introduction_date = buf->ReadDWord();
03949 break;
03950
03951 case 0x1A:
03952 rti->sorting_order = buf->ReadByte();
03953 break;
03954
03955 case 0x1B:
03956 rti->strings.name = buf->ReadWord();
03957 _string_to_grf_mapping[&rti->strings.name] = _cur.grffile->grfid;
03958 break;
03959
03960 case 0x1C:
03961 rti->maintenance_multiplier = buf->ReadWord();
03962 break;
03963
03964 case 0x1D:
03965
03966 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
03967 break;
03968
03969 default:
03970 ret = CIR_UNKNOWN;
03971 break;
03972 }
03973 }
03974
03975 return ret;
03976 }
03977
03978 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
03979 {
03980 ChangeInfoResult ret = CIR_SUCCESS;
03981
03982 extern RailtypeInfo _railtypes[RAILTYPE_END];
03983
03984 if (id + numinfo > RAILTYPE_END) {
03985 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03986 return CIR_INVALID_ID;
03987 }
03988
03989 for (int i = 0; i < numinfo; i++) {
03990 switch (prop) {
03991 case 0x08:
03992 {
03993 RailTypeLabel rtl = buf->ReadDWord();
03994 rtl = BSWAP32(rtl);
03995
03996 RailType rt = GetRailTypeByLabel(rtl, false);
03997 if (rt == INVALID_RAILTYPE) {
03998
03999 rt = AllocateRailType(rtl);
04000 }
04001
04002 _cur.grffile->railtype_map[id + i] = rt;
04003 break;
04004 }
04005
04006 case 0x09:
04007 case 0x0A:
04008 case 0x0B:
04009 case 0x0C:
04010 case 0x0D:
04011 case 0x13:
04012 case 0x14:
04013 case 0x1B:
04014 case 0x1C:
04015 buf->ReadWord();
04016 break;
04017
04018 case 0x1D:
04019 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
04020 int n = buf->ReadByte();
04021 for (int j = 0; j != n; j++) {
04022 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
04023 }
04024 break;
04025 }
04026 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
04027
04028
04029 case 0x0E:
04030 case 0x0F:
04031 case 0x18:
04032 case 0x19:
04033 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
04034 break;
04035
04036 case 0x10:
04037 case 0x11:
04038 case 0x12:
04039 case 0x15:
04040 case 0x16:
04041 case 0x1A:
04042 buf->ReadByte();
04043 break;
04044
04045 case 0x17:
04046 buf->ReadDWord();
04047 break;
04048
04049 default:
04050 ret = CIR_UNKNOWN;
04051 break;
04052 }
04053 }
04054
04055 return ret;
04056 }
04057
04058 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
04059 {
04060 ChangeInfoResult ret = CIR_SUCCESS;
04061
04062 if (airtid + numinfo > NUM_AIRPORTTILES) {
04063 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
04064 return CIR_INVALID_ID;
04065 }
04066
04067
04068 if (_cur.grffile->airtspec == NULL) {
04069 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
04070 }
04071
04072 for (int i = 0; i < numinfo; i++) {
04073 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
04074
04075 if (prop != 0x08 && tsp == NULL) {
04076 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
04077 return CIR_INVALID_ID;
04078 }
04079
04080 switch (prop) {
04081 case 0x08: {
04082 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
04083 byte subs_id = buf->ReadByte();
04084
04085 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
04086
04087 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
04088 continue;
04089 }
04090
04091
04092 if (*tilespec == NULL) {
04093 *tilespec = CallocT<AirportTileSpec>(1);
04094 tsp = *tilespec;
04095
04096 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
04097 tsp->enabled = true;
04098
04099 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
04100
04101 tsp->grf_prop.local_id = airtid + i;
04102 tsp->grf_prop.subst_id = subs_id;
04103 tsp->grf_prop.grffile = _cur.grffile;
04104 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id);
04105 }
04106 break;
04107 }
04108
04109 case 0x09: {
04110 byte override = buf->ReadByte();
04111
04112
04113 if (override >= NEW_AIRPORTTILE_OFFSET) {
04114 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
04115 continue;
04116 }
04117
04118 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
04119 break;
04120 }
04121
04122 case 0x0E:
04123 tsp->callback_mask = buf->ReadByte();
04124 break;
04125
04126 case 0x0F:
04127 tsp->animation.frames = buf->ReadByte();
04128 tsp->animation.status = buf->ReadByte();
04129 break;
04130
04131 case 0x10:
04132 tsp->animation.speed = buf->ReadByte();
04133 break;
04134
04135 case 0x11:
04136 tsp->animation.triggers = buf->ReadByte();
04137 break;
04138
04139 default:
04140 ret = CIR_UNKNOWN;
04141 break;
04142 }
04143 }
04144
04145 return ret;
04146 }
04147
04148 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
04149 {
04150 switch (cir) {
04151 default: NOT_REACHED();
04152
04153 case CIR_DISABLED:
04154
04155 return true;
04156
04157 case CIR_SUCCESS:
04158 return false;
04159
04160 case CIR_UNHANDLED:
04161 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
04162 return false;
04163
04164 case CIR_UNKNOWN:
04165 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
04166
04167
04168 case CIR_INVALID_ID: {
04169
04170 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
04171 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
04172 return true;
04173 }
04174 }
04175 }
04176
04177
04178 static void FeatureChangeInfo(ByteReader *buf)
04179 {
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191 static const VCI_Handler handler[] = {
04192 RailVehicleChangeInfo,
04193 RoadVehicleChangeInfo,
04194 ShipVehicleChangeInfo,
04195 AircraftVehicleChangeInfo,
04196 StationChangeInfo,
04197 CanalChangeInfo,
04198 BridgeChangeInfo,
04199 TownHouseChangeInfo,
04200 GlobalVarChangeInfo,
04201 IndustrytilesChangeInfo,
04202 IndustriesChangeInfo,
04203 NULL,
04204 SoundEffectChangeInfo,
04205 AirportChangeInfo,
04206 NULL,
04207 ObjectChangeInfo,
04208 RailTypeChangeInfo,
04209 AirportTilesChangeInfo,
04210 };
04211
04212 uint8 feature = buf->ReadByte();
04213 uint8 numprops = buf->ReadByte();
04214 uint numinfo = buf->ReadByte();
04215 uint engine = buf->ReadExtendedByte();
04216
04217 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
04218 feature, numprops, engine, numinfo);
04219
04220 if (feature >= lengthof(handler) || handler[feature] == NULL) {
04221 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
04222 return;
04223 }
04224
04225
04226 SetBit(_cur.grffile->grf_features, feature);
04227
04228 while (numprops-- && buf->HasData()) {
04229 uint8 prop = buf->ReadByte();
04230
04231 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
04232 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
04233 }
04234 }
04235
04236
04237 static void SafeChangeInfo(ByteReader *buf)
04238 {
04239 uint8 feature = buf->ReadByte();
04240 uint8 numprops = buf->ReadByte();
04241 uint numinfo = buf->ReadByte();
04242 buf->ReadExtendedByte();
04243
04244 if (feature == GSF_BRIDGES && numprops == 1) {
04245 uint8 prop = buf->ReadByte();
04246
04247
04248 if (prop == 0x0D) return;
04249 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
04250 uint8 prop = buf->ReadByte();
04251
04252 if (prop == 0x11) {
04253 bool is_safe = true;
04254 for (uint i = 0; i < numinfo; i++) {
04255 uint32 s = buf->ReadDWord();
04256 buf->ReadDWord();
04257 const GRFConfig *grfconfig = GetGRFConfig(s);
04258 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
04259 is_safe = false;
04260 break;
04261 }
04262 }
04263 if (is_safe) return;
04264 }
04265 }
04266
04267 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
04268
04269
04270 _cur.skip_sprites = -1;
04271 }
04272
04273
04274 static void ReserveChangeInfo(ByteReader *buf)
04275 {
04276 uint8 feature = buf->ReadByte();
04277
04278 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
04279
04280 uint8 numprops = buf->ReadByte();
04281 uint8 numinfo = buf->ReadByte();
04282 uint8 index = buf->ReadExtendedByte();
04283
04284 while (numprops-- && buf->HasData()) {
04285 uint8 prop = buf->ReadByte();
04286 ChangeInfoResult cir = CIR_SUCCESS;
04287
04288 switch (feature) {
04289 default: NOT_REACHED();
04290 case GSF_CARGOES:
04291 cir = CargoChangeInfo(index, numinfo, prop, buf);
04292 break;
04293
04294 case GSF_GLOBALVAR:
04295 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
04296 break;
04297
04298 case GSF_RAILTYPES:
04299 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
04300 break;
04301 }
04302
04303 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
04304 }
04305 }
04306
04307
04308 static void NewSpriteSet(ByteReader *buf)
04309 {
04310
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322 uint8 feature = buf->ReadByte();
04323 uint8 num_sets = buf->ReadByte();
04324 uint16 first_set = 0;
04325
04326 if (num_sets == 0 && buf->HasData(2)) {
04327
04328
04329 first_set = buf->ReadExtendedByte();
04330 num_sets = buf->ReadExtendedByte();
04331 }
04332 uint16 num_ents = buf->ReadExtendedByte();
04333
04334 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
04335
04336 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
04337 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
04338 );
04339
04340 for (int i = 0; i < num_sets * num_ents; i++) {
04341 _cur.nfo_line++;
04342 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
04343 }
04344 }
04345
04346
04347 static void SkipAct1(ByteReader *buf)
04348 {
04349 buf->ReadByte();
04350 uint8 num_sets = buf->ReadByte();
04351 uint16 num_ents = buf->ReadExtendedByte();
04352
04353 _cur.skip_sprites = num_sets * num_ents;
04354
04355 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
04356 }
04357
04358
04359
04360 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
04361 {
04362 if (HasBit(groupid, 15)) {
04363 assert(CallbackResultSpriteGroup::CanAllocateItem());
04364 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
04365 }
04366
04367 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04368 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
04369 return NULL;
04370 }
04371
04372 return _cur.spritegroups[groupid];
04373 }
04374
04383 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
04384 {
04385 if (HasBit(spriteid, 15)) {
04386 assert(CallbackResultSpriteGroup::CanAllocateItem());
04387 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
04388 }
04389
04390 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
04391 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
04392 return NULL;
04393 }
04394
04395 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
04396 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
04397
04398
04399 assert(spriteset_start + num_sprites <= _cur.spriteid);
04400
04401 assert(ResultSpriteGroup::CanAllocateItem());
04402 return new ResultSpriteGroup(spriteset_start, num_sprites);
04403 }
04404
04405
04406 static void NewSpriteGroup(ByteReader *buf)
04407 {
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418 SpriteGroup *act_group = NULL;
04419
04420 uint8 feature = buf->ReadByte();
04421 uint8 setid = buf->ReadByte();
04422 uint8 type = buf->ReadByte();
04423
04424
04425
04426
04427
04428 switch (type) {
04429
04430 case 0x81:
04431 case 0x82:
04432 case 0x85:
04433 case 0x86:
04434 case 0x89:
04435 case 0x8A:
04436 {
04437 byte varadjust;
04438 byte varsize;
04439
04440 assert(DeterministicSpriteGroup::CanAllocateItem());
04441 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
04442 act_group = group;
04443 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04444
04445 switch (GB(type, 2, 2)) {
04446 default: NOT_REACHED();
04447 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
04448 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
04449 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
04450 }
04451
04452 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
04453 adjusts.Clear();
04454
04455
04456
04457 do {
04458 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
04459
04460
04461 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
04462 adjust->variable = buf->ReadByte();
04463 if (adjust->variable == 0x7E) {
04464
04465 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
04466 } else {
04467 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
04468 }
04469
04470 varadjust = buf->ReadByte();
04471 adjust->shift_num = GB(varadjust, 0, 5);
04472 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
04473 adjust->and_mask = buf->ReadVarSize(varsize);
04474
04475 if (adjust->type != DSGA_TYPE_NONE) {
04476 adjust->add_val = buf->ReadVarSize(varsize);
04477 adjust->divmod_val = buf->ReadVarSize(varsize);
04478 } else {
04479 adjust->add_val = 0;
04480 adjust->divmod_val = 0;
04481 }
04482
04483
04484 } while (HasBit(varadjust, 5));
04485
04486 group->num_adjusts = adjusts.Length();
04487 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
04488 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
04489
04490 group->num_ranges = buf->ReadByte();
04491 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
04492
04493 for (uint i = 0; i < group->num_ranges; i++) {
04494 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04495 group->ranges[i].low = buf->ReadVarSize(varsize);
04496 group->ranges[i].high = buf->ReadVarSize(varsize);
04497 }
04498
04499 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
04500 break;
04501 }
04502
04503
04504 case 0x80:
04505 case 0x83:
04506 case 0x84:
04507 {
04508 assert(RandomizedSpriteGroup::CanAllocateItem());
04509 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
04510 act_group = group;
04511 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
04512
04513 if (HasBit(type, 2)) {
04514 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
04515 group->count = buf->ReadByte();
04516 }
04517
04518 uint8 triggers = buf->ReadByte();
04519 group->triggers = GB(triggers, 0, 7);
04520 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
04521 group->lowest_randbit = buf->ReadByte();
04522 group->num_groups = buf->ReadByte();
04523 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
04524
04525 for (uint i = 0; i < group->num_groups; i++) {
04526 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
04527 }
04528
04529 break;
04530 }
04531
04532
04533 default:
04534 {
04535 switch (feature) {
04536 case GSF_TRAINS:
04537 case GSF_ROADVEHICLES:
04538 case GSF_SHIPS:
04539 case GSF_AIRCRAFT:
04540 case GSF_STATIONS:
04541 case GSF_CANALS:
04542 case GSF_CARGOES:
04543 case GSF_AIRPORTS:
04544 case GSF_RAILTYPES:
04545 {
04546 byte num_loaded = type;
04547 byte num_loading = buf->ReadByte();
04548
04549 if (!_cur.HasValidSpriteSets(feature)) {
04550 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
04551 return;
04552 }
04553
04554 assert(RealSpriteGroup::CanAllocateItem());
04555 RealSpriteGroup *group = new RealSpriteGroup();
04556 act_group = group;
04557
04558 group->num_loaded = num_loaded;
04559 group->num_loading = num_loading;
04560 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
04561 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
04562
04563 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
04564 setid, num_loaded, num_loading);
04565
04566 for (uint i = 0; i < num_loaded; i++) {
04567 uint16 spriteid = buf->ReadWord();
04568 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04569 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
04570 }
04571
04572 for (uint i = 0; i < num_loading; i++) {
04573 uint16 spriteid = buf->ReadWord();
04574 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
04575 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
04576 }
04577
04578 break;
04579 }
04580
04581 case GSF_HOUSES:
04582 case GSF_AIRPORTTILES:
04583 case GSF_OBJECTS:
04584 case GSF_INDUSTRYTILES: {
04585 byte num_building_sprites = max((uint8)1, type);
04586
04587 assert(TileLayoutSpriteGroup::CanAllocateItem());
04588 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
04589 act_group = group;
04590
04591
04592 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
04593 break;
04594 }
04595
04596 case GSF_INDUSTRIES: {
04597 if (type > 1) {
04598 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
04599 break;
04600 }
04601
04602 assert(IndustryProductionSpriteGroup::CanAllocateItem());
04603 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04604 act_group = group;
04605 group->version = type;
04606 if (type == 0) {
04607 for (uint i = 0; i < 3; i++) {
04608 group->subtract_input[i] = (int16)buf->ReadWord();
04609 }
04610 for (uint i = 0; i < 2; i++) {
04611 group->add_output[i] = buf->ReadWord();
04612 }
04613 group->again = buf->ReadByte();
04614 } else {
04615 for (uint i = 0; i < 3; i++) {
04616 group->subtract_input[i] = buf->ReadByte();
04617 }
04618 for (uint i = 0; i < 2; i++) {
04619 group->add_output[i] = buf->ReadByte();
04620 }
04621 group->again = buf->ReadByte();
04622 }
04623 break;
04624 }
04625
04626
04627 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04628 }
04629 }
04630 }
04631
04632 _cur.spritegroups[setid] = act_group;
04633 }
04634
04635 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04636 {
04637 if (feature == GSF_OBJECTS) {
04638 switch (ctype) {
04639 case 0: return 0;
04640 case 0xFF: return CT_PURCHASE_OBJECT;
04641 default:
04642 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04643 return CT_INVALID;
04644 }
04645 }
04646
04647 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04648 if (ctype == 0xFF) return CT_PURCHASE;
04649
04650 if (_cur.grffile->cargo_max == 0) {
04651
04652 if (ctype >= 32) {
04653 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04654 return CT_INVALID;
04655 }
04656
04657 const CargoSpec *cs;
04658 FOR_ALL_CARGOSPECS(cs) {
04659 if (cs->bitnum == ctype) {
04660 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04661 return cs->Index();
04662 }
04663 }
04664
04665 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04666 return CT_INVALID;
04667 }
04668
04669
04670 if (ctype >= _cur.grffile->cargo_max) {
04671 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_max - 1);
04672 return CT_INVALID;
04673 }
04674
04675
04676 CargoLabel cl = _cur.grffile->cargo_list[ctype];
04677 if (cl == 0) {
04678 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04679 return CT_INVALID;
04680 }
04681
04682 ctype = GetCargoIDByLabel(cl);
04683 if (ctype == CT_INVALID) {
04684 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));
04685 return CT_INVALID;
04686 }
04687
04688 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);
04689 return ctype;
04690 }
04691
04692
04693 static bool IsValidGroupID(uint16 groupid, const char *function)
04694 {
04695 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
04696 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
04697 return false;
04698 }
04699
04700 return true;
04701 }
04702
04703 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04704 {
04705 static EngineID *last_engines;
04706 static uint last_engines_count;
04707 bool wagover = false;
04708
04709
04710 if (HasBit(idcount, 7)) {
04711 wagover = true;
04712
04713 idcount = GB(idcount, 0, 7);
04714
04715 if (last_engines_count == 0) {
04716 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04717 return;
04718 }
04719
04720 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04721 last_engines_count, idcount);
04722 } else {
04723 if (last_engines_count != idcount) {
04724 last_engines = ReallocT(last_engines, idcount);
04725 last_engines_count = idcount;
04726 }
04727 }
04728
04729 EngineID *engines = AllocaM(EngineID, idcount);
04730 for (uint i = 0; i < idcount; i++) {
04731 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
04732 if (e == NULL) {
04733
04734
04735
04736 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04737 return;
04738 }
04739
04740 engines[i] = e->index;
04741 if (!wagover) last_engines[i] = engines[i];
04742 }
04743
04744 uint8 cidcount = buf->ReadByte();
04745 for (uint c = 0; c < cidcount; c++) {
04746 uint8 ctype = buf->ReadByte();
04747 uint16 groupid = buf->ReadWord();
04748 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04749
04750 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04751
04752 ctype = TranslateCargo(feature, ctype);
04753 if (ctype == CT_INVALID) continue;
04754
04755 for (uint i = 0; i < idcount; i++) {
04756 EngineID engine = engines[i];
04757
04758 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04759
04760 if (wagover) {
04761 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
04762 } else {
04763 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
04764 }
04765 }
04766 }
04767
04768 uint16 groupid = buf->ReadWord();
04769 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04770
04771 grfmsg(8, "-- Default group id 0x%04X", groupid);
04772
04773 for (uint i = 0; i < idcount; i++) {
04774 EngineID engine = engines[i];
04775
04776 if (wagover) {
04777 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
04778 } else {
04779 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
04780 SetEngineGRF(engine, _cur.grffile);
04781 }
04782 }
04783 }
04784
04785
04786 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04787 {
04788 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04789 for (uint i = 0; i < idcount; i++) {
04790 cfs[i] = (CanalFeature)buf->ReadByte();
04791 }
04792
04793 uint8 cidcount = buf->ReadByte();
04794 buf->Skip(cidcount * 3);
04795
04796 uint16 groupid = buf->ReadWord();
04797 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04798
04799 for (uint i = 0; i < idcount; i++) {
04800 CanalFeature cf = cfs[i];
04801
04802 if (cf >= CF_END) {
04803 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04804 continue;
04805 }
04806
04807 _water_feature[cf].grffile = _cur.grffile;
04808 _water_feature[cf].group = _cur.spritegroups[groupid];
04809 }
04810 }
04811
04812
04813 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04814 {
04815 uint8 *stations = AllocaM(uint8, idcount);
04816 for (uint i = 0; i < idcount; i++) {
04817 stations[i] = buf->ReadByte();
04818 }
04819
04820 uint8 cidcount = buf->ReadByte();
04821 for (uint c = 0; c < cidcount; c++) {
04822 uint8 ctype = buf->ReadByte();
04823 uint16 groupid = buf->ReadWord();
04824 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04825
04826 ctype = TranslateCargo(GSF_STATIONS, ctype);
04827 if (ctype == CT_INVALID) continue;
04828
04829 for (uint i = 0; i < idcount; i++) {
04830 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04831
04832 if (statspec == NULL) {
04833 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04834 continue;
04835 }
04836
04837 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
04838 }
04839 }
04840
04841 uint16 groupid = buf->ReadWord();
04842 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04843
04844 for (uint i = 0; i < idcount; i++) {
04845 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
04846
04847 if (statspec == NULL) {
04848 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04849 continue;
04850 }
04851
04852 if (statspec->grf_prop.grffile != NULL) {
04853 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04854 continue;
04855 }
04856
04857 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
04858 statspec->grf_prop.grffile = _cur.grffile;
04859 statspec->grf_prop.local_id = stations[i];
04860 StationClass::Assign(statspec);
04861 }
04862 }
04863
04864
04865 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04866 {
04867 uint8 *houses = AllocaM(uint8, idcount);
04868 for (uint i = 0; i < idcount; i++) {
04869 houses[i] = buf->ReadByte();
04870 }
04871
04872
04873 uint8 cidcount = buf->ReadByte();
04874 buf->Skip(cidcount * 3);
04875
04876 uint16 groupid = buf->ReadWord();
04877 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04878
04879 if (_cur.grffile->housespec == NULL) {
04880 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04881 return;
04882 }
04883
04884 for (uint i = 0; i < idcount; i++) {
04885 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
04886
04887 if (hs == NULL) {
04888 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04889 continue;
04890 }
04891
04892 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04893 }
04894 }
04895
04896 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04897 {
04898 uint8 *industries = AllocaM(uint8, idcount);
04899 for (uint i = 0; i < idcount; i++) {
04900 industries[i] = buf->ReadByte();
04901 }
04902
04903
04904 uint8 cidcount = buf->ReadByte();
04905 buf->Skip(cidcount * 3);
04906
04907 uint16 groupid = buf->ReadWord();
04908 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04909
04910 if (_cur.grffile->industryspec == NULL) {
04911 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04912 return;
04913 }
04914
04915 for (uint i = 0; i < idcount; i++) {
04916 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
04917
04918 if (indsp == NULL) {
04919 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04920 continue;
04921 }
04922
04923 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04924 }
04925 }
04926
04927 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04928 {
04929 uint8 *indtiles = AllocaM(uint8, idcount);
04930 for (uint i = 0; i < idcount; i++) {
04931 indtiles[i] = buf->ReadByte();
04932 }
04933
04934
04935 uint8 cidcount = buf->ReadByte();
04936 buf->Skip(cidcount * 3);
04937
04938 uint16 groupid = buf->ReadWord();
04939 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
04940
04941 if (_cur.grffile->indtspec == NULL) {
04942 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
04943 return;
04944 }
04945
04946 for (uint i = 0; i < idcount; i++) {
04947 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
04948
04949 if (indtsp == NULL) {
04950 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
04951 continue;
04952 }
04953
04954 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
04955 }
04956 }
04957
04958 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
04959 {
04960 CargoID *cargoes = AllocaM(CargoID, idcount);
04961 for (uint i = 0; i < idcount; i++) {
04962 cargoes[i] = buf->ReadByte();
04963 }
04964
04965
04966 uint8 cidcount = buf->ReadByte();
04967 buf->Skip(cidcount * 3);
04968
04969 uint16 groupid = buf->ReadWord();
04970 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
04971
04972 for (uint i = 0; i < idcount; i++) {
04973 CargoID cid = cargoes[i];
04974
04975 if (cid >= NUM_CARGO) {
04976 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
04977 continue;
04978 }
04979
04980 CargoSpec *cs = CargoSpec::Get(cid);
04981 cs->grffile = _cur.grffile;
04982 cs->group = _cur.spritegroups[groupid];
04983 }
04984 }
04985
04986 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
04987 {
04988 if (_cur.grffile->objectspec == NULL) {
04989 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
04990 return;
04991 }
04992
04993 uint8 *objects = AllocaM(uint8, idcount);
04994 for (uint i = 0; i < idcount; i++) {
04995 objects[i] = buf->ReadByte();
04996 }
04997
04998 uint8 cidcount = buf->ReadByte();
04999 for (uint c = 0; c < cidcount; c++) {
05000 uint8 ctype = buf->ReadByte();
05001 uint16 groupid = buf->ReadWord();
05002 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
05003
05004 ctype = TranslateCargo(GSF_OBJECTS, ctype);
05005 if (ctype == CT_INVALID) continue;
05006
05007 for (uint i = 0; i < idcount; i++) {
05008 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05009
05010 if (spec == NULL) {
05011 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05012 continue;
05013 }
05014
05015 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
05016 }
05017 }
05018
05019 uint16 groupid = buf->ReadWord();
05020 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
05021
05022 for (uint i = 0; i < idcount; i++) {
05023 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
05024
05025 if (spec == NULL) {
05026 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
05027 continue;
05028 }
05029
05030 if (spec->grf_prop.grffile != NULL) {
05031 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
05032 continue;
05033 }
05034
05035 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05036 spec->grf_prop.grffile = _cur.grffile;
05037 spec->grf_prop.local_id = objects[i];
05038 }
05039 }
05040
05041 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
05042 {
05043 uint8 *railtypes = AllocaM(uint8, idcount);
05044 for (uint i = 0; i < idcount; i++) {
05045 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
05046 }
05047
05048 uint8 cidcount = buf->ReadByte();
05049 for (uint c = 0; c < cidcount; c++) {
05050 uint8 ctype = buf->ReadByte();
05051 uint16 groupid = buf->ReadWord();
05052 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
05053
05054 if (ctype >= RTSG_END) continue;
05055
05056 extern RailtypeInfo _railtypes[RAILTYPE_END];
05057 for (uint i = 0; i < idcount; i++) {
05058 if (railtypes[i] != INVALID_RAILTYPE) {
05059 RailtypeInfo *rti = &_railtypes[railtypes[i]];
05060
05061 rti->grffile[ctype] = _cur.grffile;
05062 rti->group[ctype] = _cur.spritegroups[groupid];
05063 }
05064 }
05065 }
05066
05067
05068 buf->ReadWord();
05069 }
05070
05071 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
05072 {
05073 uint8 *airports = AllocaM(uint8, idcount);
05074 for (uint i = 0; i < idcount; i++) {
05075 airports[i] = buf->ReadByte();
05076 }
05077
05078
05079 uint8 cidcount = buf->ReadByte();
05080 buf->Skip(cidcount * 3);
05081
05082 uint16 groupid = buf->ReadWord();
05083 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
05084
05085 if (_cur.grffile->airportspec == NULL) {
05086 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
05087 return;
05088 }
05089
05090 for (uint i = 0; i < idcount; i++) {
05091 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
05092
05093 if (as == NULL) {
05094 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
05095 continue;
05096 }
05097
05098 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05099 }
05100 }
05101
05102 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
05103 {
05104 uint8 *airptiles = AllocaM(uint8, idcount);
05105 for (uint i = 0; i < idcount; i++) {
05106 airptiles[i] = buf->ReadByte();
05107 }
05108
05109
05110 uint8 cidcount = buf->ReadByte();
05111 buf->Skip(cidcount * 3);
05112
05113 uint16 groupid = buf->ReadWord();
05114 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
05115
05116 if (_cur.grffile->airtspec == NULL) {
05117 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
05118 return;
05119 }
05120
05121 for (uint i = 0; i < idcount; i++) {
05122 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
05123
05124 if (airtsp == NULL) {
05125 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
05126 continue;
05127 }
05128
05129 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
05130 }
05131 }
05132
05133
05134
05135 static void FeatureMapSpriteGroup(ByteReader *buf)
05136 {
05137
05138
05139
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151 uint8 feature = buf->ReadByte();
05152 uint8 idcount = buf->ReadByte();
05153
05154
05155 if (idcount == 0) {
05156
05157 buf->ReadByte();
05158 uint16 groupid = buf->ReadWord();
05159 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
05160
05161 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
05162
05163 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
05164 return;
05165 }
05166
05167
05168 SetBit(_cur.grffile->grf_features, feature);
05169
05170 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
05171
05172 switch (feature) {
05173 case GSF_TRAINS:
05174 case GSF_ROADVEHICLES:
05175 case GSF_SHIPS:
05176 case GSF_AIRCRAFT:
05177 VehicleMapSpriteGroup(buf, feature, idcount);
05178 return;
05179
05180 case GSF_CANALS:
05181 CanalMapSpriteGroup(buf, idcount);
05182 return;
05183
05184 case GSF_STATIONS:
05185 StationMapSpriteGroup(buf, idcount);
05186 return;
05187
05188 case GSF_HOUSES:
05189 TownHouseMapSpriteGroup(buf, idcount);
05190 return;
05191
05192 case GSF_INDUSTRIES:
05193 IndustryMapSpriteGroup(buf, idcount);
05194 return;
05195
05196 case GSF_INDUSTRYTILES:
05197 IndustrytileMapSpriteGroup(buf, idcount);
05198 return;
05199
05200 case GSF_CARGOES:
05201 CargoMapSpriteGroup(buf, idcount);
05202 return;
05203
05204 case GSF_AIRPORTS:
05205 AirportMapSpriteGroup(buf, idcount);
05206 return;
05207
05208 case GSF_OBJECTS:
05209 ObjectMapSpriteGroup(buf, idcount);
05210 break;
05211
05212 case GSF_RAILTYPES:
05213 RailTypeMapSpriteGroup(buf, idcount);
05214 break;
05215
05216 case GSF_AIRPORTTILES:
05217 AirportTileMapSpriteGroup(buf, idcount);
05218 return;
05219
05220 default:
05221 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
05222 return;
05223 }
05224 }
05225
05226
05227 static void FeatureNewName(ByteReader *buf)
05228 {
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241
05242
05243
05244
05245 bool new_scheme = _cur.grffile->grf_version >= 7;
05246
05247 uint8 feature = buf->ReadByte();
05248 uint8 lang = buf->ReadByte();
05249 uint8 num = buf->ReadByte();
05250 bool generic = HasBit(lang, 7);
05251 uint16 id;
05252 if (generic) {
05253 id = buf->ReadWord();
05254 } else if (feature <= GSF_AIRCRAFT) {
05255 id = buf->ReadExtendedByte();
05256 } else {
05257 id = buf->ReadByte();
05258 }
05259
05260 ClrBit(lang, 7);
05261
05262 uint16 endid = id + num;
05263
05264 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
05265 id, endid, feature, lang);
05266
05267 for (; id < endid && buf->HasData(); id++) {
05268 const char *name = buf->ReadString();
05269 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
05270
05271 switch (feature) {
05272 case GSF_TRAINS:
05273 case GSF_ROADVEHICLES:
05274 case GSF_SHIPS:
05275 case GSF_AIRCRAFT:
05276 if (!generic) {
05277 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
05278 if (e == NULL) break;
05279 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
05280 e->info.string_id = string;
05281 } else {
05282 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05283 }
05284 break;
05285
05286 case GSF_INDUSTRIES: {
05287 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05288 break;
05289 }
05290
05291 case GSF_HOUSES:
05292 default:
05293 switch (GB(id, 8, 8)) {
05294 case 0xC4:
05295 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05296 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05297 } else {
05298 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
05299 StationClass::SetName(cls_id, AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED));
05300 }
05301 break;
05302
05303 case 0xC5:
05304 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
05305 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
05306 } else {
05307 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05308 }
05309 break;
05310
05311 case 0xC7:
05312 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
05313 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
05314 } else {
05315 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05316 }
05317 break;
05318
05319 case 0xC9:
05320 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
05321 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
05322 } else {
05323 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
05324 }
05325 break;
05326
05327 case 0xD0:
05328 case 0xD1:
05329 case 0xD2:
05330 case 0xD3:
05331 case 0xDC:
05332 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
05333 break;
05334
05335 default:
05336 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
05337 break;
05338 }
05339 break;
05340 }
05341 }
05342 }
05343
05352 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
05353 {
05354
05355 if (offset >= max_sprites) {
05356 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
05357 uint orig_num = num;
05358 num = 0;
05359 return orig_num;
05360 }
05361
05362 if (offset + num > max_sprites) {
05363 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
05364 uint orig_num = num;
05365 num = max(max_sprites - offset, 0);
05366 return orig_num - num;
05367 }
05368
05369 return 0;
05370 }
05371
05372
05374 enum Action5BlockType {
05375 A5BLOCK_FIXED,
05376 A5BLOCK_ALLOW_OFFSET,
05377 A5BLOCK_INVALID,
05378 };
05380 struct Action5Type {
05381 Action5BlockType block_type;
05382 SpriteID sprite_base;
05383 uint16 min_sprites;
05384 uint16 max_sprites;
05385 const char *name;
05386 };
05387
05389 static const Action5Type _action5_types[] = {
05390
05391 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
05392 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
05393 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
05394 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
05395 { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
05396 { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
05397 { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
05398 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
05399 { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
05400 { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
05401 { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
05402 { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
05403 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
05404 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
05405 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
05406 { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
05407 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
05408 { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
05409 { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
05410 { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
05411 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
05412 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
05413 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
05414 };
05415
05416
05417 static void GraphicsNew(ByteReader *buf)
05418 {
05419
05420
05421
05422
05423
05424
05425
05426 uint8 type = buf->ReadByte();
05427 uint16 num = buf->ReadExtendedByte();
05428 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
05429 ClrBit(type, 7);
05430
05431 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
05432
05433
05434 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
05435 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++);
05436 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++);
05437 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++);
05438 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++);
05439 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++);
05440 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++);
05441 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++);
05442 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++);
05443 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++);
05444 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++);
05445 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
05446 return;
05447 }
05448
05449
05450 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
05451 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
05452 _cur.skip_sprites = num;
05453 return;
05454 }
05455
05456 const Action5Type *action5_type = &_action5_types[type];
05457
05458
05459
05460
05461 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
05462 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
05463 offset = 0;
05464 }
05465
05466
05467
05468 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
05469 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);
05470 _cur.skip_sprites = num;
05471 return;
05472 }
05473
05474
05475 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
05476 SpriteID replace = action5_type->sprite_base + offset;
05477
05478
05479 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);
05480
05481 for (; num > 0; num--) {
05482 _cur.nfo_line++;
05483 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line);
05484 }
05485
05486 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
05487
05488 _cur.skip_sprites = skip_num;
05489 }
05490
05491
05492 static void SkipAct5(ByteReader *buf)
05493 {
05494
05495 buf->ReadByte();
05496
05497
05498 _cur.skip_sprites = buf->ReadExtendedByte();
05499
05500 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
05501 }
05502
05508 void CheckForMissingSprites()
05509 {
05510
05511
05512 bool missing = false;
05513 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
05514 const Action5Type *type = &_action5_types[i];
05515 if (type->block_type == A5BLOCK_INVALID) continue;
05516
05517 for (uint j = 0; j < type->max_sprites; j++) {
05518 if (!SpriteExists(type->sprite_base + j)) {
05519 DEBUG(grf, 0, "%s sprites are missing", type->name);
05520 missing = true;
05521
05522 break;
05523 }
05524 }
05525 }
05526
05527 if (missing) {
05528 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
05529 }
05530 }
05531
05543 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
05544 {
05545 switch (param) {
05546 case 0x00:
05547 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
05548 return true;
05549
05550 case 0x01:
05551 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
05552 return true;
05553
05554 case 0x02: {
05555 YearMonthDay ymd;
05556 ConvertDateToYMD(_date, &ymd);
05557 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
05558 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
05559 return true;
05560 }
05561
05562 case 0x03:
05563 *value = _settings_game.game_creation.landscape;
05564 return true;
05565
05566 case 0x06:
05567 *value = _settings_game.vehicle.road_side << 4;
05568 return true;
05569
05570 case 0x09:
05571 *value = _date_fract * 885;
05572 return true;
05573
05574 case 0x0A:
05575 *value = _tick_counter;
05576 return true;
05577
05578 case 0x0B: {
05579 uint major = 2;
05580 uint minor = 6;
05581 uint revision = 1;
05582 uint build = 1382;
05583 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05584 return true;
05585 }
05586
05587 case 0x0D:
05588 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
05589 return true;
05590
05591 case 0x0E:
05592 *value = _cur.grffile->traininfo_vehicle_pitch;
05593 return true;
05594
05595 case 0x0F:
05596 *value = 0;
05597 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
05598 if (_settings_game.vehicle.disable_elrails) {
05599
05600 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05601 } else {
05602 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05603
05604 }
05605 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05606 return true;
05607
05608 case 0x11:
05609 *value = 0;
05610 return true;
05611
05612 case 0x12:
05613 *value = _game_mode;
05614 return true;
05615
05616
05617
05618
05619
05620
05621
05622 case 0x1A:
05623 *value = UINT_MAX;
05624 return true;
05625
05626 case 0x1B:
05627 *value = 0x3F;
05628 return true;
05629
05630 case 0x1D:
05631 *value = 1;
05632 return true;
05633
05634 case 0x1E:
05635 *value = _misc_grf_features;
05636
05637
05638 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05639 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05640 return true;
05641
05642
05643
05644 case 0x20: {
05645 byte snowline = GetSnowLine();
05646 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
05647 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
05648 } else {
05649
05650 *value = 0xFF;
05651 }
05652 return true;
05653 }
05654
05655 case 0x21:
05656 *value = _openttd_newgrf_version;
05657 return true;
05658
05659 case 0x22:
05660 *value = _settings_game.difficulty.diff_level;
05661 return true;
05662
05663 case 0x23:
05664 *value = _date;
05665 return true;
05666
05667 case 0x24:
05668 *value = _cur_year;
05669 return true;
05670
05671 default: return false;
05672 }
05673 }
05674
05675 static uint32 GetParamVal(byte param, uint32 *cond_val)
05676 {
05677
05678 uint32 value;
05679 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
05680
05681
05682 switch (param) {
05683 case 0x84: {
05684 uint32 res = 0;
05685
05686 if (_cur.stage > GLS_INIT) SetBit(res, 0);
05687 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
05688 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
05689 return res;
05690 }
05691
05692 case 0x85:
05693 if (cond_val == NULL) {
05694
05695 return 0;
05696 } else {
05697 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05698 *cond_val %= 0x20;
05699 return param_val;
05700 }
05701
05702 case 0x88:
05703 return 0;
05704
05705
05706
05707 default:
05708
05709 if (param < 0x80) return _cur.grffile->GetParam(param);
05710
05711
05712 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05713 return UINT_MAX;
05714 }
05715 }
05716
05717
05718 static void CfgApply(ByteReader *buf)
05719 {
05720
05721
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731
05732 size_t pos = FioGetPos();
05733 uint16 num = FioReadWord();
05734 uint8 type = FioReadByte();
05735 byte *preload_sprite = NULL;
05736
05737
05738 if (type == 0xFF) {
05739 preload_sprite = MallocT<byte>(num);
05740 FioReadBlock(preload_sprite, num);
05741 }
05742
05743
05744 FioSeekTo(pos, SEEK_SET);
05745
05746 if (type != 0xFF) {
05747 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05748 free(preload_sprite);
05749 return;
05750 }
05751
05752 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
05753 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05754 if (it != _grf_line_to_action6_sprite_override.end()) {
05755 free(preload_sprite);
05756 preload_sprite = _grf_line_to_action6_sprite_override[location];
05757 } else {
05758 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05759 }
05760
05761
05762
05763 for (;;) {
05764 uint i;
05765 uint param_num;
05766 uint param_size;
05767 uint offset;
05768 bool add_value;
05769
05770
05771 param_num = buf->ReadByte();
05772 if (param_num == 0xFF) break;
05773
05774
05775
05776 param_size = buf->ReadByte();
05777
05778
05779
05780 add_value = HasBit(param_size, 7);
05781 param_size = GB(param_size, 0, 7);
05782
05783
05784 offset = buf->ReadExtendedByte();
05785
05786
05787
05788 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
05789 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05790 break;
05791 }
05792
05793 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05794
05795 bool carry = false;
05796 for (i = 0; i < param_size && offset + i < num; i++) {
05797 uint32 value = GetParamVal(param_num + i / 4, NULL);
05798
05799
05800 if (i % 4 == 0) carry = false;
05801
05802 if (add_value) {
05803 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05804 preload_sprite[offset + i] = GB(new_value, 0, 8);
05805
05806 carry = new_value >= 256;
05807 } else {
05808 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05809 }
05810 }
05811 }
05812 }
05813
05823 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05824 {
05825 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05826 error->data = strdup(_cur.grfconfig->GetName());
05827 }
05828
05829
05830
05831 static void SkipIf(ByteReader *buf)
05832 {
05833
05834
05835
05836
05837
05838
05839
05840
05841 uint32 cond_val = 0;
05842 uint32 mask = 0;
05843 bool result;
05844
05845 uint8 param = buf->ReadByte();
05846 uint8 paramsize = buf->ReadByte();
05847 uint8 condtype = buf->ReadByte();
05848
05849 if (condtype < 2) {
05850
05851 paramsize = 1;
05852 }
05853
05854 switch (paramsize) {
05855 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05856 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05857 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05858 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05859 default: break;
05860 }
05861
05862 if (param < 0x80 && _cur.grffile->param_end <= param) {
05863 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05864 return;
05865 }
05866
05867 uint32 param_val = GetParamVal(param, &cond_val);
05868
05869 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05880
05881
05882 GRFConfig *c = GetGRFConfig(cond_val, mask);
05883
05884 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
05885 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05886 c = NULL;
05887 }
05888
05889 if (condtype != 10 && c == NULL) {
05890 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05891 return;
05892 }
05893
05894 switch (condtype) {
05895
05896 case 0x06:
05897 result = c->status == GCS_ACTIVATED;
05898 break;
05899
05900 case 0x07:
05901 result = c->status != GCS_ACTIVATED;
05902 break;
05903
05904 case 0x08:
05905 result = c->status == GCS_INITIALISED;
05906 break;
05907
05908 case 0x09:
05909 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05910 break;
05911
05912 case 0x0A:
05913
05914 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05915 break;
05916
05917 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05918 }
05919 } else {
05920
05921 switch (condtype) {
05922 case 0x00: result = !!(param_val & (1 << cond_val));
05923 break;
05924 case 0x01: result = !(param_val & (1 << cond_val));
05925 break;
05926 case 0x02: result = (param_val & mask) == cond_val;
05927 break;
05928 case 0x03: result = (param_val & mask) != cond_val;
05929 break;
05930 case 0x04: result = (param_val & mask) < cond_val;
05931 break;
05932 case 0x05: result = (param_val & mask) > cond_val;
05933 break;
05934 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05935 break;
05936 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05937 break;
05938 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
05939 break;
05940 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
05941 break;
05942
05943 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
05944 }
05945 }
05946
05947 if (!result) {
05948 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
05949 return;
05950 }
05951
05952 uint8 numsprites = buf->ReadByte();
05953
05954
05955
05956
05957
05958 GRFLabel *choice = NULL;
05959 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
05960 if (label->label != numsprites) continue;
05961
05962
05963 if (choice == NULL) choice = label;
05964
05965 if (label->nfo_line > _cur.nfo_line) {
05966 choice = label;
05967 break;
05968 }
05969 }
05970
05971 if (choice != NULL) {
05972 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
05973 FioSeekTo(choice->pos, SEEK_SET);
05974 _cur.nfo_line = choice->nfo_line;
05975 return;
05976 }
05977
05978 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
05979 _cur.skip_sprites = numsprites;
05980 if (_cur.skip_sprites == 0) {
05981
05982
05983
05984 _cur.skip_sprites = -1;
05985
05986
05987 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
05988 DisableGrf();
05989 }
05990 }
05991 }
05992
05993
05994
05995 static void ScanInfo(ByteReader *buf)
05996 {
05997 uint8 grf_version = buf->ReadByte();
05998 uint32 grfid = buf->ReadDWord();
05999 const char *name = buf->ReadString();
06000
06001 _cur.grfconfig->ident.grfid = grfid;
06002
06003 if (grf_version < 2 || grf_version > 8) {
06004 SetBit(_cur.grfconfig->flags, GCF_INVALID);
06005 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);
06006 }
06007
06008
06009 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
06010
06011 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
06012
06013 if (buf->HasData()) {
06014 const char *info = buf->ReadString();
06015 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
06016 }
06017
06018
06019 _cur.skip_sprites = -1;
06020 }
06021
06022
06023 static void GRFInfo(ByteReader *buf)
06024 {
06025
06026
06027
06028
06029
06030
06031
06032 uint8 version = buf->ReadByte();
06033 uint32 grfid = buf->ReadDWord();
06034 const char *name = buf->ReadString();
06035
06036 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
06037 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
06038 return;
06039 }
06040
06041 if (_cur.grffile->grfid != grfid) {
06042 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));
06043 _cur.grffile->grfid = grfid;
06044 }
06045
06046 _cur.grffile->grf_version = version;
06047 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
06048
06049
06050 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);
06051 }
06052
06053
06054 static void SpriteReplace(ByteReader *buf)
06055 {
06056
06057
06058
06059
06060
06061
06062
06063
06064 uint8 num_sets = buf->ReadByte();
06065
06066 for (uint i = 0; i < num_sets; i++) {
06067 uint8 num_sprites = buf->ReadByte();
06068 uint16 first_sprite = buf->ReadWord();
06069
06070 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
06071 i, num_sprites, first_sprite
06072 );
06073
06074 for (uint j = 0; j < num_sprites; j++) {
06075 int load_index = first_sprite + j;
06076 _cur.nfo_line++;
06077 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line);
06078
06079
06080
06081 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
06082 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06083 }
06084 }
06085 }
06086 }
06087
06088
06089 static void SkipActA(ByteReader *buf)
06090 {
06091 uint8 num_sets = buf->ReadByte();
06092
06093 for (uint i = 0; i < num_sets; i++) {
06094
06095 _cur.skip_sprites += buf->ReadByte();
06096
06097 buf->ReadWord();
06098 }
06099
06100 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
06101 }
06102
06103
06104 static void GRFLoadError(ByteReader *buf)
06105 {
06106
06107
06108
06109
06110
06111
06112
06113
06114
06115
06116
06117
06118
06119
06120
06121 static const StringID msgstr[] = {
06122 STR_NEWGRF_ERROR_VERSION_NUMBER,
06123 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
06124 STR_NEWGRF_ERROR_UNSET_SWITCH,
06125 STR_NEWGRF_ERROR_INVALID_PARAMETER,
06126 STR_NEWGRF_ERROR_LOAD_BEFORE,
06127 STR_NEWGRF_ERROR_LOAD_AFTER,
06128 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
06129 };
06130
06131 static const StringID sevstr[] = {
06132 STR_NEWGRF_ERROR_MSG_INFO,
06133 STR_NEWGRF_ERROR_MSG_WARNING,
06134 STR_NEWGRF_ERROR_MSG_ERROR,
06135 STR_NEWGRF_ERROR_MSG_FATAL
06136 };
06137
06138 byte severity = buf->ReadByte();
06139 byte lang = buf->ReadByte();
06140 byte message_id = buf->ReadByte();
06141
06142
06143 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
06144
06145
06146
06147 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
06148 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
06149 return;
06150 }
06151 ClrBit(severity, 7);
06152
06153 if (severity >= lengthof(sevstr)) {
06154 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
06155 severity = 2;
06156 } else if (severity == 3) {
06157
06158
06159 DisableGrf();
06160
06161
06162 delete _cur.grfconfig->error;
06163 _cur.grfconfig->error = NULL;
06164 }
06165
06166 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
06167 grfmsg(7, "GRFLoadError: Invalid message id.");
06168 return;
06169 }
06170
06171 if (buf->Remaining() <= 1) {
06172 grfmsg(7, "GRFLoadError: No message data supplied.");
06173 return;
06174 }
06175
06176
06177 if (_cur.grfconfig->error != NULL) return;
06178
06179 GRFError *error = new GRFError(sevstr[severity]);
06180
06181 if (message_id == 0xFF) {
06182
06183 if (buf->HasData()) {
06184 const char *message = buf->ReadString();
06185
06186 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
06187 } else {
06188 grfmsg(7, "GRFLoadError: No custom message supplied.");
06189 error->custom_message = strdup("");
06190 }
06191 } else {
06192 error->message = msgstr[message_id];
06193 }
06194
06195 if (buf->HasData()) {
06196 const char *data = buf->ReadString();
06197
06198 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
06199 } else {
06200 grfmsg(7, "GRFLoadError: No message data supplied.");
06201 error->data = strdup("");
06202 }
06203
06204
06205 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
06206 uint param_number = buf->ReadByte();
06207 error->param_value[i] = _cur.grffile->GetParam(param_number);
06208 }
06209
06210 _cur.grfconfig->error = error;
06211 }
06212
06213
06214 static void GRFComment(ByteReader *buf)
06215 {
06216
06217
06218
06219
06220 if (!buf->HasData()) return;
06221
06222 const char *text = buf->ReadString();
06223 grfmsg(2, "GRFComment: %s", text);
06224 }
06225
06226
06227 static void SafeParamSet(ByteReader *buf)
06228 {
06229 uint8 target = buf->ReadByte();
06230
06231
06232 if (target < 0x80) return;
06233
06234
06235
06236
06237
06238
06239 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06240
06241
06242 _cur.skip_sprites = -1;
06243 }
06244
06245
06246 static uint32 GetPatchVariable(uint8 param)
06247 {
06248 switch (param) {
06249
06250 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
06251
06252
06253 case 0x0E: return _settings_game.vehicle.freight_trains;
06254
06255
06256 case 0x0F: return 0;
06257
06258
06259
06260
06261 case 0x10:
06262 switch (_settings_game.vehicle.plane_speed) {
06263 default:
06264 case 4: return 1;
06265 case 3: return 2;
06266 case 2: return 2;
06267 case 1: return 4;
06268 }
06269
06270
06271
06272 case 0x11: return SPR_2CCMAP_BASE;
06273
06274
06275
06276
06277
06278
06279
06280
06281
06282
06283
06284
06285 case 0x13: {
06286 byte map_bits = 0;
06287 byte log_X = MapLogX() - 6;
06288 byte log_Y = MapLogY() - 6;
06289 byte max_edge = max(log_X, log_Y);
06290
06291 if (log_X == log_Y) {
06292 SetBit(map_bits, 0);
06293 } else {
06294 if (max_edge == log_Y) SetBit(map_bits, 1);
06295 }
06296
06297 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
06298 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
06299 }
06300
06301
06302 case 0x14:
06303 return MAX_TILE_HEIGHT;
06304
06305 default:
06306 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
06307 return 0;
06308 }
06309 }
06310
06311
06312 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
06313 {
06314 uint start = 0;
06315 uint size = 0;
06316
06317 if (op == 6) {
06318
06319 return grm[_cur.grffile->GetParam(target)];
06320 }
06321
06322
06323 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
06324
06325 for (uint i = start; i < num_ids; i++) {
06326 if (grm[i] == 0) {
06327 size++;
06328 } else {
06329 if (op == 2 || op == 3) break;
06330 start = i + 1;
06331 size = 0;
06332 }
06333
06334 if (size == count) break;
06335 }
06336
06337 if (size == count) {
06338
06339 if (op == 0 || op == 3) {
06340 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
06341 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
06342 }
06343 return start;
06344 }
06345
06346
06347 if (op != 4 && op != 5) {
06348
06349 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
06350 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06351 return UINT_MAX;
06352 }
06353
06354 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
06355 return UINT_MAX;
06356 }
06357
06358
06360 static void ParamSet(ByteReader *buf)
06361 {
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380
06381
06382
06383
06384 uint8 target = buf->ReadByte();
06385 uint8 oper = buf->ReadByte();
06386 uint32 src1 = buf->ReadByte();
06387 uint32 src2 = buf->ReadByte();
06388
06389 uint32 data = 0;
06390 if (buf->Remaining() >= 4) data = buf->ReadDWord();
06391
06392
06393
06394
06395
06396
06397
06398 if (HasBit(oper, 7)) {
06399 if (target < 0x80 && target < _cur.grffile->param_end) {
06400 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
06401 return;
06402 }
06403
06404 oper = GB(oper, 0, 7);
06405 }
06406
06407 if (src2 == 0xFE) {
06408 if (GB(data, 0, 8) == 0xFF) {
06409 if (data == 0x0000FFFF) {
06410
06411 src1 = GetPatchVariable(src1);
06412 } else {
06413
06414 uint8 op = src1;
06415 uint8 feature = GB(data, 8, 8);
06416 uint16 count = GB(data, 16, 16);
06417
06418 if (_cur.stage == GLS_RESERVE) {
06419 if (feature == 0x08) {
06420
06421 if (op == 0) {
06422
06423 if (_cur.spriteid + count >= 16384) {
06424 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
06425 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
06426 return;
06427 }
06428
06429
06430 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
06431 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
06432 _cur.spriteid += count;
06433 }
06434 }
06435
06436 src1 = 0;
06437 } else if (_cur.stage == GLS_ACTIVATION) {
06438 switch (feature) {
06439 case 0x00:
06440 case 0x01:
06441 case 0x02:
06442 case 0x03:
06443 if (!_settings_game.vehicle.dynamic_engines) {
06444 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
06445 if (_cur.skip_sprites == -1) return;
06446 } else {
06447
06448 switch (op) {
06449 case 2:
06450 case 3:
06451 src1 = _cur.grffile->GetParam(target);
06452 break;
06453
06454 default:
06455 src1 = 0;
06456 break;
06457 }
06458 }
06459 break;
06460
06461 case 0x08:
06462 switch (op) {
06463 case 0:
06464
06465 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
06466 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
06467 break;
06468
06469 case 1:
06470 src1 = _cur.spriteid;
06471 break;
06472
06473 default:
06474 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
06475 return;
06476 }
06477 break;
06478
06479 case 0x0B:
06480
06481 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
06482 if (_cur.skip_sprites == -1) return;
06483 break;
06484
06485 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
06486 }
06487 } else {
06488
06489 src1 = 0;
06490 }
06491 }
06492 } else {
06493
06494 const GRFFile *file = GetFileByGRFID(data);
06495 GRFConfig *c = GetGRFConfig(data);
06496 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
06497
06498 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
06499 src1 = 0;
06500 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
06501 src1 = 0;
06502 } else if (src1 == 0xFE) {
06503 src1 = c->version;
06504 } else {
06505 src1 = file->GetParam(src1);
06506 }
06507 }
06508 } else {
06509
06510
06511
06512
06513
06514 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
06515 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
06516 }
06517
06518
06519
06520
06521
06522
06523
06524 uint32 res;
06525 switch (oper) {
06526 case 0x00:
06527 res = src1;
06528 break;
06529
06530 case 0x01:
06531 res = src1 + src2;
06532 break;
06533
06534 case 0x02:
06535 res = src1 - src2;
06536 break;
06537
06538 case 0x03:
06539 res = src1 * src2;
06540 break;
06541
06542 case 0x04:
06543 res = (int32)src1 * (int32)src2;
06544 break;
06545
06546 case 0x05:
06547 if ((int32)src2 < 0) {
06548 res = src1 >> -(int32)src2;
06549 } else {
06550 res = src1 << src2;
06551 }
06552 break;
06553
06554 case 0x06:
06555 if ((int32)src2 < 0) {
06556 res = (int32)src1 >> -(int32)src2;
06557 } else {
06558 res = (int32)src1 << src2;
06559 }
06560 break;
06561
06562 case 0x07:
06563 res = src1 & src2;
06564 break;
06565
06566 case 0x08:
06567 res = src1 | src2;
06568 break;
06569
06570 case 0x09:
06571 if (src2 == 0) {
06572 res = src1;
06573 } else {
06574 res = src1 / src2;
06575 }
06576 break;
06577
06578 case 0x0A:
06579 if (src2 == 0) {
06580 res = src1;
06581 } else {
06582 res = (int32)src1 / (int32)src2;
06583 }
06584 break;
06585
06586 case 0x0B:
06587 if (src2 == 0) {
06588 res = src1;
06589 } else {
06590 res = src1 % src2;
06591 }
06592 break;
06593
06594 case 0x0C:
06595 if (src2 == 0) {
06596 res = src1;
06597 } else {
06598 res = (int32)src1 % (int32)src2;
06599 }
06600 break;
06601
06602 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06603 }
06604
06605 switch (target) {
06606 case 0x8E:
06607 _cur.grffile->traininfo_vehicle_pitch = res;
06608 break;
06609
06610 case 0x8F: {
06611 extern RailtypeInfo _railtypes[RAILTYPE_END];
06612 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06613 if (_settings_game.vehicle.disable_elrails) {
06614 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06615 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06616 } else {
06617 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06618 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06619 }
06620 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06621 break;
06622 }
06623
06624
06625 case 0x93:
06626 case 0x94:
06627 case 0x95:
06628 case 0x96:
06629 case 0x97:
06630 case 0x99:
06631 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06632 break;
06633
06634 case 0x9E:
06635 _misc_grf_features = res;
06636
06637
06638 _cur.grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06639
06640
06641 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
06642 break;
06643
06644 case 0x9F:
06645 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06646 break;
06647
06648 default:
06649 if (target < 0x80) {
06650 _cur.grffile->param[target] = res;
06651
06652 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
06653 } else {
06654 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06655 }
06656 break;
06657 }
06658 }
06659
06660
06661 static void SafeGRFInhibit(ByteReader *buf)
06662 {
06663
06664
06665
06666
06667
06668 uint8 num = buf->ReadByte();
06669
06670 for (uint i = 0; i < num; i++) {
06671 uint32 grfid = buf->ReadDWord();
06672
06673
06674 if (grfid != _cur.grfconfig->ident.grfid) {
06675 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
06676
06677
06678 _cur.skip_sprites = -1;
06679
06680 return;
06681 }
06682 }
06683 }
06684
06685
06686 static void GRFInhibit(ByteReader *buf)
06687 {
06688
06689
06690
06691
06692
06693 uint8 num = buf->ReadByte();
06694
06695 for (uint i = 0; i < num; i++) {
06696 uint32 grfid = buf->ReadDWord();
06697 GRFConfig *file = GetGRFConfig(grfid);
06698
06699
06700 if (file != NULL && file != _cur.grfconfig) {
06701 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06702 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06703 error->data = strdup(_cur.grfconfig->GetName());
06704 }
06705 }
06706 }
06707
06709 static void FeatureTownName(ByteReader *buf)
06710 {
06711
06712
06713
06714
06715
06716
06717
06718 uint32 grfid = _cur.grffile->grfid;
06719
06720 GRFTownName *townname = AddGRFTownName(grfid);
06721
06722 byte id = buf->ReadByte();
06723 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06724
06725 if (HasBit(id, 7)) {
06726
06727 ClrBit(id, 7);
06728 bool new_scheme = _cur.grffile->grf_version >= 7;
06729
06730 byte lang = buf->ReadByte();
06731
06732 byte nb_gen = townname->nb_gen;
06733 do {
06734 ClrBit(lang, 7);
06735
06736 const char *name = buf->ReadString();
06737
06738 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06739 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06740 free(lang_name);
06741
06742 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06743
06744 lang = buf->ReadByte();
06745 } while (lang != 0);
06746 townname->id[nb_gen] = id;
06747 townname->nb_gen++;
06748 }
06749
06750 byte nb = buf->ReadByte();
06751 grfmsg(6, "FeatureTownName: %u parts", nb);
06752
06753 townname->nbparts[id] = nb;
06754 townname->partlist[id] = CallocT<NamePartList>(nb);
06755
06756 for (int i = 0; i < nb; i++) {
06757 byte nbtext = buf->ReadByte();
06758 townname->partlist[id][i].bitstart = buf->ReadByte();
06759 townname->partlist[id][i].bitcount = buf->ReadByte();
06760 townname->partlist[id][i].maxprob = 0;
06761 townname->partlist[id][i].partcount = nbtext;
06762 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06763 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);
06764
06765 for (int j = 0; j < nbtext; j++) {
06766 byte prob = buf->ReadByte();
06767
06768 if (HasBit(prob, 7)) {
06769 byte ref_id = buf->ReadByte();
06770
06771 if (townname->nbparts[ref_id] == 0) {
06772 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06773 DelGRFTownName(grfid);
06774 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06775 return;
06776 }
06777
06778 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06779 townname->partlist[id][i].parts[j].data.id = ref_id;
06780 } else {
06781 const char *text = buf->ReadString();
06782 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06783 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06784 }
06785 townname->partlist[id][i].parts[j].prob = prob;
06786 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06787 }
06788 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06789 }
06790 }
06791
06793 static void DefineGotoLabel(ByteReader *buf)
06794 {
06795
06796
06797
06798
06799
06800 byte nfo_label = buf->ReadByte();
06801
06802 GRFLabel *label = MallocT<GRFLabel>(1);
06803 label->label = nfo_label;
06804 label->nfo_line = _cur.nfo_line;
06805 label->pos = FioGetPos();
06806 label->next = NULL;
06807
06808
06809 if (_cur.grffile->label == NULL) {
06810 _cur.grffile->label = label;
06811 } else {
06812
06813 GRFLabel *l;
06814 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
06815 l->next = label;
06816 }
06817
06818 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06819 }
06820
06821
06822 static void GRFSound(ByteReader *buf)
06823 {
06824
06825
06826
06827
06828 uint16 num = buf->ReadWord();
06829
06830 _cur.data_blocks = num;
06831 _cur.data_type = GDT_SOUND;
06832
06833 if (_cur.grffile->sound_offset == 0) {
06834 _cur.grffile->sound_offset = GetNumSounds();
06835 _cur.grffile->num_sounds = num;
06836 }
06837 }
06838
06839
06840 static void SkipAct11(ByteReader *buf)
06841 {
06842
06843
06844
06845
06846 _cur.skip_sprites = buf->ReadWord();
06847
06848 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
06849 }
06850
06851 static void ImportGRFSound(ByteReader *buf)
06852 {
06853 const GRFFile *file;
06854 SoundEntry *sound = AllocateSound();
06855 uint32 grfid = buf->ReadDWord();
06856 SoundID sound_id = buf->ReadWord();
06857
06858 file = GetFileByGRFID(grfid);
06859 if (file == NULL || file->sound_offset == 0) {
06860 grfmsg(1, "ImportGRFSound: Source file not available");
06861 return;
06862 }
06863
06864 if (sound_id >= file->num_sounds) {
06865 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06866 return;
06867 }
06868
06869 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06870
06871 *sound = *GetSound(file->sound_offset + sound_id);
06872
06873
06874 sound->volume = 128;
06875 sound->priority = 0;
06876 }
06877
06878
06879 static void GRFImportBlock(ByteReader *buf)
06880 {
06881 if (_cur.data_blocks == 0) {
06882 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
06883 return;
06884 }
06885
06886 _cur.data_blocks--;
06887
06888
06889
06890 if (buf->ReadByte() != _cur.data_type) {
06891 grfmsg(1, "GRFImportBlock: Import type mismatch");
06892 }
06893
06894 switch (_cur.data_type) {
06895 case GDT_SOUND: ImportGRFSound(buf); break;
06896 default: NOT_REACHED();
06897 }
06898 }
06899
06900 static void LoadGRFSound(ByteReader *buf)
06901 {
06902
06903
06904 SoundEntry *sound = AllocateSound();
06905
06906 if (buf->ReadDWord() != BSWAP32('RIFF')) {
06907 grfmsg(1, "LoadGRFSound: Missing RIFF header");
06908 return;
06909 }
06910
06911 uint32 total_size = buf->ReadDWord();
06912 if (total_size > buf->Remaining()) {
06913 grfmsg(1, "LoadGRFSound: RIFF was truncated");
06914 return;
06915 }
06916
06917 if (buf->ReadDWord() != BSWAP32('WAVE')) {
06918 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
06919 return;
06920 }
06921
06922 while (total_size >= 8) {
06923 uint32 tag = buf->ReadDWord();
06924 uint32 size = buf->ReadDWord();
06925 total_size -= 8;
06926 if (total_size < size) {
06927 grfmsg(1, "LoadGRFSound: Invalid RIFF");
06928 return;
06929 }
06930 total_size -= size;
06931
06932 switch (tag) {
06933 case ' tmf':
06934
06935 if (size < 16 || buf->ReadWord() != 1) {
06936 grfmsg(1, "LoadGRFSound: Invalid audio format");
06937 return;
06938 }
06939 sound->channels = buf->ReadWord();
06940 sound->rate = buf->ReadDWord();
06941 buf->ReadDWord();
06942 buf->ReadWord();
06943 sound->bits_per_sample = buf->ReadWord();
06944
06945
06946 size -= 16;
06947 break;
06948
06949 case 'atad':
06950 sound->file_size = size;
06951 sound->file_offset = FioGetPos() - buf->Remaining();
06952 sound->file_slot = _cur.file_index;
06953
06954
06955 sound->volume = 0x80;
06956 sound->priority = 0;
06957
06958 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
06959 return;
06960
06961 default:
06962
06963 break;
06964 }
06965
06966
06967 for (; size > 0; size--) buf->ReadByte();
06968 }
06969
06970 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
06971
06972
06973 MemSetT(sound, 0);
06974 }
06975
06977 static void LoadFontGlyph(ByteReader *buf)
06978 {
06979
06980
06981
06982
06983
06984
06985
06986 uint8 num_def = buf->ReadByte();
06987
06988 for (uint i = 0; i < num_def; i++) {
06989 FontSize size = (FontSize)buf->ReadByte();
06990 uint8 num_char = buf->ReadByte();
06991 uint16 base_char = buf->ReadWord();
06992
06993 if (size >= FS_END) {
06994 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
06995 }
06996
06997 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
06998
06999 for (uint c = 0; c < num_char; c++) {
07000 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
07001 _cur.nfo_line++;
07002 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line);
07003 }
07004 }
07005 }
07006
07008 static void SkipAct12(ByteReader *buf)
07009 {
07010
07011
07012
07013
07014
07015
07016
07017 uint8 num_def = buf->ReadByte();
07018
07019 for (uint i = 0; i < num_def; i++) {
07020
07021 buf->ReadByte();
07022
07023
07024 _cur.skip_sprites += buf->ReadByte();
07025
07026
07027 buf->ReadWord();
07028 }
07029
07030 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
07031 }
07032
07034 static void TranslateGRFStrings(ByteReader *buf)
07035 {
07036
07037
07038
07039
07040
07041
07042
07043 uint32 grfid = buf->ReadDWord();
07044 const GRFConfig *c = GetGRFConfig(grfid);
07045 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
07046 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
07047 return;
07048 }
07049
07050 if (c->status == GCS_INITIALISED) {
07051
07052
07053 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
07054
07055 char tmp[256];
07056 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
07057 error->data = strdup(tmp);
07058
07059 return;
07060 }
07061
07062
07063
07064
07065
07066
07067 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
07068 byte num_strings = buf->ReadByte();
07069 uint16 first_id = buf->ReadWord();
07070
07071 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
07072 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
07073 return;
07074 }
07075
07076 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
07077 const char *string = buf->ReadString();
07078
07079 if (StrEmpty(string)) {
07080 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
07081 continue;
07082 }
07083
07084 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
07085 }
07086 }
07087
07089 static bool ChangeGRFName(byte langid, const char *str)
07090 {
07091 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
07092 return true;
07093 }
07094
07096 static bool ChangeGRFDescription(byte langid, const char *str)
07097 {
07098 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
07099 return true;
07100 }
07101
07103 static bool ChangeGRFURL(byte langid, const char *str)
07104 {
07105 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
07106 return true;
07107 }
07108
07110 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
07111 {
07112 if (len != 1) {
07113 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
07114 buf->Skip(len);
07115 } else {
07116 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
07117 }
07118 return true;
07119 }
07120
07122 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
07123 {
07124 if (len != 1) {
07125 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
07126 buf->Skip(len);
07127 } else {
07128 char data = buf->ReadByte();
07129 GRFPalette pal = GRFP_GRF_UNSET;
07130 switch (data) {
07131 case '*':
07132 case 'A': pal = GRFP_GRF_ANY; break;
07133 case 'W': pal = GRFP_GRF_WINDOWS; break;
07134 case 'D': pal = GRFP_GRF_DOS; break;
07135 default:
07136 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
07137 break;
07138 }
07139 if (pal != GRFP_GRF_UNSET) {
07140 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
07141 _cur.grfconfig->palette |= pal;
07142 }
07143 }
07144 return true;
07145 }
07146
07148 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
07149 {
07150 if (len != 1) {
07151 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
07152 buf->Skip(len);
07153 } else {
07154 char data = buf->ReadByte();
07155 GRFPalette pal = GRFP_BLT_UNSET;
07156 switch (data) {
07157 case '8': pal = GRFP_BLT_UNSET; break;
07158 case '3': pal = GRFP_BLT_32BPP; break;
07159 default:
07160 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
07161 return true;
07162 }
07163 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
07164 _cur.grfconfig->palette |= pal;
07165 }
07166 return true;
07167 }
07168
07170 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
07171 {
07172 if (len != 4) {
07173 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
07174 buf->Skip(len);
07175 } else {
07176
07177 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07178 }
07179 return true;
07180 }
07181
07183 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
07184 {
07185 if (len != 4) {
07186 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
07187 buf->Skip(len);
07188 } else {
07189 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
07190 if (_cur.grfconfig->version == 0) {
07191 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
07192 _cur.grfconfig->min_loadable_version = 0;
07193 }
07194 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
07195 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
07196 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
07197 }
07198 }
07199 return true;
07200 }
07201
07202 static GRFParameterInfo *_cur_parameter;
07203
07205 static bool ChangeGRFParamName(byte langid, const char *str)
07206 {
07207 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
07208 return true;
07209 }
07210
07212 static bool ChangeGRFParamDescription(byte langid, const char *str)
07213 {
07214 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
07215 return true;
07216 }
07217
07219 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
07220 {
07221 if (len != 1) {
07222 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
07223 buf->Skip(len);
07224 } else {
07225 GRFParameterType type = (GRFParameterType)buf->ReadByte();
07226 if (type < PTYPE_END) {
07227 _cur_parameter->type = type;
07228 } else {
07229 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
07230 }
07231 }
07232 return true;
07233 }
07234
07236 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
07237 {
07238 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
07239 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
07240 buf->Skip(len);
07241 } else if (len != 8) {
07242 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
07243 buf->Skip(len);
07244 } else {
07245 _cur_parameter->min_value = buf->ReadDWord();
07246 _cur_parameter->max_value = buf->ReadDWord();
07247 }
07248 return true;
07249 }
07250
07252 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
07253 {
07254 if (len < 1 || len > 3) {
07255 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
07256 buf->Skip(len);
07257 } else {
07258 byte param_nr = buf->ReadByte();
07259 if (param_nr >= lengthof(_cur.grfconfig->param)) {
07260 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
07261 buf->Skip(len - 1);
07262 } else {
07263 _cur_parameter->param_nr = param_nr;
07264 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
07265 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
07266 }
07267 }
07268
07269 return true;
07270 }
07271
07273 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
07274 {
07275 if (len != 4) {
07276 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
07277 buf->Skip(len);
07278 } else {
07279 _cur_parameter->def_value = buf->ReadDWord();
07280 }
07281 _cur.grfconfig->has_param_defaults = true;
07282 return true;
07283 }
07284
07285 typedef bool (*DataHandler)(size_t, ByteReader *);
07286 typedef bool (*TextHandler)(byte, const char *str);
07287 typedef bool (*BranchHandler)(ByteReader *);
07288
07296 struct AllowedSubtags {
07298 AllowedSubtags() :
07299 id(0),
07300 type(0)
07301 {}
07302
07308 AllowedSubtags(uint32 id, DataHandler handler) :
07309 id(id),
07310 type('B')
07311 {
07312 this->handler.data = handler;
07313 }
07314
07320 AllowedSubtags(uint32 id, TextHandler handler) :
07321 id(id),
07322 type('T')
07323 {
07324 this->handler.text = handler;
07325 }
07326
07332 AllowedSubtags(uint32 id, BranchHandler handler) :
07333 id(id),
07334 type('C')
07335 {
07336 this->handler.call_handler = true;
07337 this->handler.u.branch = handler;
07338 }
07339
07345 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
07346 id(id),
07347 type('C')
07348 {
07349 this->handler.call_handler = false;
07350 this->handler.u.subtags = subtags;
07351 }
07352
07353 uint32 id;
07354 byte type;
07355 union {
07356 DataHandler data;
07357 TextHandler text;
07358 struct {
07359 union {
07360 BranchHandler branch;
07361 AllowedSubtags *subtags;
07362 } u;
07363 bool call_handler;
07364 };
07365 } handler;
07366 };
07367
07368 static bool SkipUnknownInfo(ByteReader *buf, byte type);
07369 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
07370
07377 static bool ChangeGRFParamValueNames(ByteReader *buf)
07378 {
07379 byte type = buf->ReadByte();
07380 while (type != 0) {
07381 uint32 id = buf->ReadDWord();
07382 if (type != 'T' || id > _cur_parameter->max_value) {
07383 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
07384 if (!SkipUnknownInfo(buf, type)) return false;
07385 type = buf->ReadByte();
07386 continue;
07387 }
07388
07389 byte langid = buf->ReadByte();
07390 const char *name_string = buf->ReadString();
07391
07392 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
07393 if (val_name != _cur_parameter->value_names.End()) {
07394 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
07395 } else {
07396 GRFText *list = NULL;
07397 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
07398 _cur_parameter->value_names.Insert(id, list);
07399 }
07400
07401 type = buf->ReadByte();
07402 }
07403 return true;
07404 }
07405
07407 AllowedSubtags _tags_parameters[] = {
07408 AllowedSubtags('NAME', ChangeGRFParamName),
07409 AllowedSubtags('DESC', ChangeGRFParamDescription),
07410 AllowedSubtags('TYPE', ChangeGRFParamType),
07411 AllowedSubtags('LIMI', ChangeGRFParamLimits),
07412 AllowedSubtags('MASK', ChangeGRFParamMask),
07413 AllowedSubtags('VALU', ChangeGRFParamValueNames),
07414 AllowedSubtags('DFLT', ChangeGRFParamDefault),
07415 AllowedSubtags()
07416 };
07417
07424 static bool HandleParameterInfo(ByteReader *buf)
07425 {
07426 byte type = buf->ReadByte();
07427 while (type != 0) {
07428 uint32 id = buf->ReadDWord();
07429 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
07430 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
07431 if (!SkipUnknownInfo(buf, type)) return false;
07432 type = buf->ReadByte();
07433 continue;
07434 }
07435
07436 if (id >= _cur.grfconfig->param_info.Length()) {
07437 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
07438 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
07439 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
07440 }
07441 if (_cur.grfconfig->param_info[id] == NULL) {
07442 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
07443 }
07444 _cur_parameter = _cur.grfconfig->param_info[id];
07445
07446 if (!HandleNodes(buf, _tags_parameters)) return false;
07447 type = buf->ReadByte();
07448 }
07449 return true;
07450 }
07451
07453 AllowedSubtags _tags_info[] = {
07454 AllowedSubtags('NAME', ChangeGRFName),
07455 AllowedSubtags('DESC', ChangeGRFDescription),
07456 AllowedSubtags('URL_', ChangeGRFURL),
07457 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
07458 AllowedSubtags('PALS', ChangeGRFPalette),
07459 AllowedSubtags('BLTR', ChangeGRFBlitter),
07460 AllowedSubtags('VRSN', ChangeGRFVersion),
07461 AllowedSubtags('MINV', ChangeGRFMinVersion),
07462 AllowedSubtags('PARA', HandleParameterInfo),
07463 AllowedSubtags()
07464 };
07465
07467 AllowedSubtags _tags_root[] = {
07468 AllowedSubtags('INFO', _tags_info),
07469 AllowedSubtags()
07470 };
07471
07472
07479 static bool SkipUnknownInfo(ByteReader *buf, byte type)
07480 {
07481
07482 switch (type) {
07483 case 'C': {
07484 byte new_type = buf->ReadByte();
07485 while (new_type != 0) {
07486 buf->ReadDWord();
07487 if (!SkipUnknownInfo(buf, new_type)) return false;
07488 new_type = buf->ReadByte();
07489 }
07490 break;
07491 }
07492
07493 case 'T':
07494 buf->ReadByte();
07495 buf->ReadString();
07496 break;
07497
07498 case 'B': {
07499 uint16 size = buf->ReadWord();
07500 buf->Skip(size);
07501 break;
07502 }
07503
07504 default:
07505 return false;
07506 }
07507
07508 return true;
07509 }
07510
07519 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
07520 {
07521 uint i = 0;
07522 AllowedSubtags *tag;
07523 while ((tag = &subtags[i++])->type != 0) {
07524 if (tag->id != BSWAP32(id) || tag->type != type) continue;
07525 switch (type) {
07526 default: NOT_REACHED();
07527
07528 case 'T': {
07529 byte langid = buf->ReadByte();
07530 return tag->handler.text(langid, buf->ReadString());
07531 }
07532
07533 case 'B': {
07534 size_t len = buf->ReadWord();
07535 if (buf->Remaining() < len) return false;
07536 return tag->handler.data(len, buf);
07537 }
07538
07539 case 'C': {
07540 if (tag->handler.call_handler) {
07541 return tag->handler.u.branch(buf);
07542 }
07543 return HandleNodes(buf, tag->handler.u.subtags);
07544 }
07545 }
07546 }
07547 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
07548 return SkipUnknownInfo(buf, type);
07549 }
07550
07557 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
07558 {
07559 byte type = buf->ReadByte();
07560 while (type != 0) {
07561 uint32 id = buf->ReadDWord();
07562 if (!HandleNode(type, id, buf, subtags)) return false;
07563 type = buf->ReadByte();
07564 }
07565 return true;
07566 }
07567
07572 static void StaticGRFInfo(ByteReader *buf)
07573 {
07574
07575 HandleNodes(buf, _tags_root);
07576 }
07577
07579 static void GRFDataBlock(ByteReader *buf)
07580 {
07581
07582
07583 if (_cur.data_blocks == 0) {
07584 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
07585 return;
07586 }
07587
07588 uint8 name_len = buf->ReadByte();
07589 const char *name = reinterpret_cast<const char *>(buf->Data());
07590 buf->Skip(name_len);
07591
07592
07593 if (buf->ReadByte() != 0) {
07594 grfmsg(2, "GRFDataBlock: Name not properly terminated");
07595 return;
07596 }
07597
07598 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
07599
07600 _cur.data_blocks--;
07601
07602 switch (_cur.data_type) {
07603 case GDT_SOUND: LoadGRFSound(buf); break;
07604 default: NOT_REACHED();
07605 }
07606 }
07607
07613 static void GRFUnsafe(ByteReader *buf)
07614 {
07615 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
07616
07617
07618 _cur.skip_sprites = -1;
07619 }
07620
07621
07623 static void InitializeGRFSpecial()
07624 {
07625 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
07626 | (1 << 0x0D)
07627 | (1 << 0x0E)
07628 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
07629 | (0 << 0x10)
07630 | (1 << 0x12)
07631 | (1 << 0x13)
07632 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
07633 | (1 << 0x1B)
07634 | (1 << 0x1D)
07635 | (1 << 0x1E);
07636
07637 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
07638 | (1 << 0x08)
07639 | (1 << 0x09)
07640 | (0 << 0x0B)
07641 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
07642 | (1 << 0x12)
07643 | (1 << 0x13)
07644 | (1 << 0x14)
07645 | (1 << 0x16)
07646 | (1 << 0x17)
07647 | (1 << 0x18)
07648 | (1 << 0x19)
07649 | (1 << 0x1A)
07650 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
07651 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07652
07653 _ttdpatch_flags[2] = (1 << 0x01)
07654 | (1 << 0x03)
07655 | (1 << 0x0A)
07656 | (0 << 0x0B)
07657 | (0 << 0x0C)
07658 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07659 | (1 << 0x0E)
07660 | (1 << 0x0F)
07661 | (0 << 0x10)
07662 | (0 << 0x11)
07663 | (1 << 0x12)
07664 | (1 << 0x13)
07665 | (1 << 0x14)
07666 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07667 | (1 << 0x16)
07668 | (1 << 0x17)
07669 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07670 | (1 << 0x19)
07671 | (1 << 0x1A)
07672 | (1 << 0x1B)
07673 | (1 << 0x1C)
07674 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07675 | (1 << 0x1E)
07676 | (0 << 0x1F);
07677
07678 _ttdpatch_flags[3] = (0 << 0x00)
07679 | (1 << 0x01)
07680 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07681 | (1 << 0x03)
07682 | (0 << 0x04)
07683 | (1 << 0x05)
07684 | (1 << 0x06)
07685 | (1 << 0x07)
07686 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07687 | (0 << 0x09)
07688 | (0 << 0x0A)
07689 | (1 << 0x0B)
07690 | (1 << 0x0C)
07691 | (1 << 0x0D)
07692 | (1 << 0x0E)
07693 | (1 << 0x0F)
07694 | (1 << 0x10)
07695 | (1 << 0x11)
07696 | (1 << 0x12)
07697 | (0 << 0x13)
07698 | (1 << 0x14)
07699 | (0 << 0x15)
07700 | (1 << 0x16)
07701 | (1 << 0x17)
07702 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07703 | (1 << 0x1E)
07704 | (1 << 0x1F);
07705 }
07706
07708 static void ResetCustomStations()
07709 {
07710 const GRFFile * const *end = _grf_files.End();
07711 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07712 StationSpec **&stations = (*file)->stations;
07713 if (stations == NULL) continue;
07714 for (uint i = 0; i < MAX_STATIONS; i++) {
07715 if (stations[i] == NULL) continue;
07716 StationSpec *statspec = stations[i];
07717
07718 delete[] statspec->renderdata;
07719
07720
07721 if (!statspec->copied_layouts) {
07722 for (uint l = 0; l < statspec->lengths; l++) {
07723 for (uint p = 0; p < statspec->platforms[l]; p++) {
07724 free(statspec->layouts[l][p]);
07725 }
07726 free(statspec->layouts[l]);
07727 }
07728 free(statspec->layouts);
07729 free(statspec->platforms);
07730 }
07731
07732
07733 free(statspec);
07734 }
07735
07736
07737 free(stations);
07738 stations = NULL;
07739 }
07740 }
07741
07743 static void ResetCustomHouses()
07744 {
07745 const GRFFile * const *end = _grf_files.End();
07746 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07747 HouseSpec **&housespec = (*file)->housespec;
07748 if (housespec == NULL) continue;
07749 for (uint i = 0; i < HOUSE_MAX; i++) {
07750 free(housespec[i]);
07751 }
07752
07753 free(housespec);
07754 housespec = NULL;
07755 }
07756 }
07757
07759 static void ResetCustomAirports()
07760 {
07761 const GRFFile * const *end = _grf_files.End();
07762 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07763 AirportSpec **aslist = (*file)->airportspec;
07764 if (aslist != NULL) {
07765 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07766 AirportSpec *as = aslist[i];
07767
07768 if (as != NULL) {
07769
07770 for (int j = 0; j < as->num_table; j++) {
07771
07772 free(as->table[j]);
07773 }
07774 free(as->table);
07775 free(as->depot_table);
07776
07777 free(as);
07778 }
07779 }
07780 free(aslist);
07781 (*file)->airportspec = NULL;
07782 }
07783
07784 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07785 if (airporttilespec != NULL) {
07786 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07787 free(airporttilespec[i]);
07788 }
07789 free(airporttilespec);
07790 airporttilespec = NULL;
07791 }
07792 }
07793 }
07794
07796 static void ResetCustomIndustries()
07797 {
07798 const GRFFile * const *end = _grf_files.End();
07799 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07800 IndustrySpec **&industryspec = (*file)->industryspec;
07801 IndustryTileSpec **&indtspec = (*file)->indtspec;
07802
07803
07804
07805 if (industryspec != NULL) {
07806 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07807 IndustrySpec *ind = industryspec[i];
07808 if (ind == NULL) continue;
07809
07810
07811 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07812 free(ind->random_sounds);
07813 }
07814
07815
07816 CleanIndustryTileTable(ind);
07817
07818 free(ind);
07819 }
07820
07821 free(industryspec);
07822 industryspec = NULL;
07823 }
07824
07825 if (indtspec == NULL) continue;
07826 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07827 free(indtspec[i]);
07828 }
07829
07830 free(indtspec);
07831 indtspec = NULL;
07832 }
07833 }
07834
07836 static void ResetCustomObjects()
07837 {
07838 const GRFFile * const *end = _grf_files.End();
07839 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07840 ObjectSpec **&objectspec = (*file)->objectspec;
07841 if (objectspec == NULL) continue;
07842 for (uint i = 0; i < NUM_OBJECTS; i++) {
07843 free(objectspec[i]);
07844 }
07845
07846 free(objectspec);
07847 objectspec = NULL;
07848 }
07849 }
07850
07852 static void ResetNewGRF()
07853 {
07854 const GRFFile * const *end = _grf_files.End();
07855 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07856 GRFFile *f = *file;
07857 free(f->filename);
07858 free(f->cargo_list);
07859 free(f->railtype_list);
07860 delete [] f->language_map;
07861 free(f);
07862 }
07863
07864 _grf_files.Clear();
07865 _cur.grffile = NULL;
07866 }
07867
07869 static void ResetNewGRFErrors()
07870 {
07871 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07872 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07873 delete c->error;
07874 c->error = NULL;
07875 }
07876 }
07877 }
07878
07883 void ResetNewGRFData()
07884 {
07885 CleanUpStrings();
07886 CleanUpGRFTownNames();
07887
07888
07889 SetupEngines();
07890
07891
07892 ResetBridges();
07893
07894
07895 ResetRailTypes();
07896
07897
07898 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07899
07900
07901 Engine *e;
07902 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07903 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07904 }
07905
07906
07907 memset(&_grm_engines, 0, sizeof(_grm_engines));
07908 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
07909
07910
07911 ResetGenericCallbacks();
07912
07913
07914 ResetPriceBaseMultipliers();
07915
07916
07917 ResetCurrencies();
07918
07919
07920 ResetCustomHouses();
07921 ResetHouses();
07922
07923
07924 ResetCustomIndustries();
07925 ResetIndustries();
07926
07927
07928 ObjectClass::Reset();
07929 ResetCustomObjects();
07930 ResetObjects();
07931
07932
07933 StationClass::Reset();
07934 ResetCustomStations();
07935
07936
07937 AirportClass::Reset();
07938 ResetCustomAirports();
07939 AirportSpec::ResetAirports();
07940 AirportTileSpec::ResetAirportTiles();
07941
07942
07943 memset(_water_feature, 0, sizeof(_water_feature));
07944
07945
07946 ClearSnowLine();
07947
07948
07949 ResetNewGRF();
07950
07951
07952 ResetNewGRFErrors();
07953
07954
07955 SetupCargoForClimate(_settings_game.game_creation.landscape);
07956
07957
07958 _misc_grf_features = 0;
07959
07960 _loaded_newgrf_features.has_2CC = false;
07961 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07962 _loaded_newgrf_features.has_newhouses = false;
07963 _loaded_newgrf_features.has_newindustries = false;
07964 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07965
07966
07967 _grf_id_overrides.clear();
07968
07969 InitializeSoundPool();
07970 _spritegroup_pool.CleanPool();
07971 }
07972
07976 void ResetPersistentNewGRFData()
07977 {
07978
07979 _engine_mngr.ResetToDefaultMapping();
07980 _house_mngr.ResetMapping();
07981 _industry_mngr.ResetMapping();
07982 _industile_mngr.ResetMapping();
07983 _airport_mngr.ResetMapping();
07984 _airporttile_mngr.ResetMapping();
07985 }
07986
07991 static void BuildCargoTranslationMap()
07992 {
07993 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
07994
07995 for (CargoID c = 0; c < NUM_CARGO; c++) {
07996 const CargoSpec *cs = CargoSpec::Get(c);
07997 if (!cs->IsValid()) continue;
07998
07999 if (_cur.grffile->cargo_max == 0) {
08000
08001 _cur.grffile->cargo_map[c] = cs->bitnum;
08002 } else {
08003
08004 for (uint i = 0; i < _cur.grffile->cargo_max; i++) {
08005 if (cs->label == _cur.grffile->cargo_list[i]) {
08006 _cur.grffile->cargo_map[c] = i;
08007 break;
08008 }
08009 }
08010 }
08011 }
08012 }
08013
08018 static void InitNewGRFFile(const GRFConfig *config)
08019 {
08020 GRFFile *newfile = GetFileByFilename(config->filename);
08021 if (newfile != NULL) {
08022
08023 _cur.grffile = newfile;
08024 return;
08025 }
08026
08027 newfile = CallocT<GRFFile>(1);
08028
08029 newfile->filename = strdup(config->filename);
08030 newfile->grfid = config->ident.grfid;
08031
08032
08033 newfile->traininfo_vehicle_pitch = 0;
08034 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
08035
08036
08037 for (Price i = PR_BEGIN; i < PR_END; i++) {
08038 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
08039 }
08040
08041
08042 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
08043 newfile->railtype_map[0] = RAILTYPE_RAIL;
08044 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
08045 newfile->railtype_map[2] = RAILTYPE_MONO;
08046 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
08047
08048
08049
08050 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
08051 memset(newfile->param, 0, sizeof(newfile->param));
08052
08053 assert(config->num_params <= lengthof(config->param));
08054 newfile->param_end = config->num_params;
08055 if (newfile->param_end > 0) {
08056 MemCpyT(newfile->param, config->param, newfile->param_end);
08057 }
08058
08059 *_grf_files.Append() = _cur.grffile = newfile;
08060 }
08061
08062
08067 static const CargoLabel _default_refitmasks_rail[] = {
08068 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
08069 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
08070 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08071 'PLST', 'FZDR',
08072 0 };
08073
08074 static const CargoLabel _default_refitmasks_road[] = {
08075 0 };
08076
08077 static const CargoLabel _default_refitmasks_ships[] = {
08078 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
08079 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
08080 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
08081 'PLST', 'FZDR',
08082 0 };
08083
08084 static const CargoLabel _default_refitmasks_aircraft[] = {
08085 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
08086 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
08087 0 };
08088
08089 static const CargoLabel * const _default_refitmasks[] = {
08090 _default_refitmasks_rail,
08091 _default_refitmasks_road,
08092 _default_refitmasks_ships,
08093 _default_refitmasks_aircraft,
08094 };
08095
08096
08100 static void CalculateRefitMasks()
08101 {
08102 Engine *e;
08103
08104 FOR_ALL_ENGINES(e) {
08105 EngineID engine = e->index;
08106 EngineInfo *ei = &e->info;
08107 bool only_defaultcargo;
08108 const uint8 *cargo_map_for_first_refittable = NULL;
08109
08110
08111 if (_gted[engine].refitmask_valid) {
08112 uint32 mask = 0;
08113 uint32 not_mask = 0;
08114 uint32 xor_mask = 0;
08115
08116
08117
08118 only_defaultcargo = (ei->refit_mask == 0 && _gted[engine].cargo_allowed == 0 && _gted[engine].ctt_include_mask == 0);
08119
08120 const GRFFile *file = _gted[engine].refitmask_grf;
08121 if (file == NULL) file = e->GetGRF();
08122 if (file != NULL && file->grf_version >= 8 && file->cargo_max != 0) {
08123 cargo_map_for_first_refittable = file->cargo_map;
08124 }
08125
08126 if (ei->refit_mask != 0) {
08127 if (file != NULL && file->cargo_max != 0) {
08128
08129 uint num_cargo = min(32, file->cargo_max);
08130 for (uint i = 0; i < num_cargo; i++) {
08131 if (!HasBit(ei->refit_mask, i)) continue;
08132
08133 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
08134 if (c == CT_INVALID) continue;
08135
08136 SetBit(xor_mask, c);
08137 }
08138 } else {
08139
08140 const CargoSpec *cs;
08141 FOR_ALL_CARGOSPECS(cs) {
08142 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
08143 }
08144 }
08145 }
08146
08147 if (_gted[engine].cargo_allowed != 0) {
08148
08149 const CargoSpec *cs;
08150 FOR_ALL_CARGOSPECS(cs) {
08151 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
08152 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
08153 }
08154 }
08155
08156 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
08157
08158
08159 ei->refit_mask |= _gted[engine].ctt_include_mask;
08160 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
08161 } else {
08162 uint32 xor_mask = 0;
08163
08164
08165 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
08166 const CargoLabel *cl = _default_refitmasks[e->type];
08167 for (uint i = 0;; i++) {
08168 if (cl[i] == 0) break;
08169
08170 CargoID cargo = GetCargoIDByLabel(cl[i]);
08171 if (cargo == CT_INVALID) continue;
08172
08173 SetBit(xor_mask, cargo);
08174 }
08175 }
08176
08177 ei->refit_mask = xor_mask & _cargo_mask;
08178
08179
08180 only_defaultcargo = (ei->refit_mask == 0);
08181 }
08182
08183
08184
08185 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
08186 ei->cargo_type = CT_INVALID;
08187 }
08188
08189
08190
08191 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
08192 if (cargo_map_for_first_refittable != NULL) {
08193
08194 byte best_local_slot = 0xFF;
08195 CargoID cargo_type;
08196 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
08197 byte local_slot = cargo_map_for_first_refittable[cargo_type];
08198 if (local_slot < best_local_slot) {
08199 best_local_slot = local_slot;
08200 ei->cargo_type = cargo_type;
08201 }
08202 }
08203 }
08204
08205 if (ei->cargo_type == CT_INVALID) {
08206
08207 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
08208 }
08209 }
08210 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
08211
08212
08213 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
08214 ei->refit_mask = 0;
08215 }
08216 }
08217 }
08218
08220 static void FinaliseCanals()
08221 {
08222 for (uint i = 0; i < CF_END; i++) {
08223 if (_water_feature[i].grffile != NULL) {
08224 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
08225 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
08226 }
08227 }
08228 }
08229
08231 static void FinaliseEngineArray()
08232 {
08233 Engine *e;
08234
08235 FOR_ALL_ENGINES(e) {
08236 if (e->GetGRF() == NULL) {
08237 const EngineIDMapping &eid = _engine_mngr[e->index];
08238 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
08239 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
08240 }
08241 }
08242
08243
08244
08245
08246 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
08247 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
08248 }
08249
08250
08251 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
08252 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
08253 SetBit(_loaded_newgrf_features.used_liveries, ls);
08254
08255
08256 if (e->type == VEH_TRAIN) {
08257 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
08258 switch (ls) {
08259 case LS_STEAM:
08260 case LS_DIESEL:
08261 case LS_ELECTRIC:
08262 case LS_MONORAIL:
08263 case LS_MAGLEV:
08264 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
08265 break;
08266
08267 case LS_DMU:
08268 case LS_EMU:
08269 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
08270 break;
08271
08272 default: NOT_REACHED();
08273 }
08274 }
08275 }
08276 }
08277 }
08278
08280 static void FinaliseCargoArray()
08281 {
08282 for (CargoID c = 0; c < NUM_CARGO; c++) {
08283 CargoSpec *cs = CargoSpec::Get(c);
08284 if (!cs->IsValid()) {
08285 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
08286 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
08287 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
08288 }
08289 }
08290 }
08291
08303 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
08304 {
08305 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
08306 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
08307 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
08308 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
08309 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
08310 hs->enabled = false;
08311 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);
08312 return false;
08313 }
08314
08315
08316
08317
08318 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
08319 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
08320 hs->enabled = false;
08321 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);
08322 return false;
08323 }
08324
08325
08326
08327 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
08328 hs->enabled = false;
08329 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);
08330 return false;
08331 }
08332
08333
08334 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
08335 hs->enabled = false;
08336 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);
08337 return false;
08338 }
08339
08340 return true;
08341 }
08342
08349 static void EnsureEarlyHouse(HouseZones bitmask)
08350 {
08351 Year min_year = MAX_YEAR;
08352
08353 for (int i = 0; i < HOUSE_MAX; i++) {
08354 HouseSpec *hs = HouseSpec::Get(i);
08355 if (hs == NULL || !hs->enabled) continue;
08356 if ((hs->building_availability & bitmask) != bitmask) continue;
08357 if (hs->min_year < min_year) min_year = hs->min_year;
08358 }
08359
08360 if (min_year == 0) return;
08361
08362 for (int i = 0; i < HOUSE_MAX; i++) {
08363 HouseSpec *hs = HouseSpec::Get(i);
08364 if (hs == NULL || !hs->enabled) continue;
08365 if ((hs->building_availability & bitmask) != bitmask) continue;
08366 if (hs->min_year == min_year) hs->min_year = 0;
08367 }
08368 }
08369
08376 static void FinaliseHouseArray()
08377 {
08378
08379
08380
08381
08382
08383
08384
08385
08386
08387 const GRFFile * const *end = _grf_files.End();
08388 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08389 HouseSpec **&housespec = (*file)->housespec;
08390 if (housespec == NULL) continue;
08391
08392 for (int i = 0; i < HOUSE_MAX; i++) {
08393 HouseSpec *hs = housespec[i];
08394
08395 if (hs == NULL) continue;
08396
08397 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
08398 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
08399 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
08400
08401 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
08402
08403 _house_mngr.SetEntitySpec(hs);
08404 }
08405 }
08406
08407 for (int i = 0; i < HOUSE_MAX; i++) {
08408 HouseSpec *hs = HouseSpec::Get(i);
08409 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
08410 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
08411 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
08412
08413
08414
08415 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
08416
08417
08418
08419
08420
08421
08422
08423 hs->building_flags = TILE_NO_FLAG;
08424 }
08425 }
08426
08427 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
08428 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
08429 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
08430 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
08431 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
08432 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
08433
08434 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
08435 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
08436 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
08437 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
08438 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
08439 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
08440 }
08441 }
08442
08448 static void FinaliseIndustriesArray()
08449 {
08450 const GRFFile * const *end = _grf_files.End();
08451 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08452 IndustrySpec **&industryspec = (*file)->industryspec;
08453 IndustryTileSpec **&indtspec = (*file)->indtspec;
08454 if (industryspec != NULL) {
08455 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
08456 IndustrySpec *indsp = industryspec[i];
08457
08458 if (indsp != NULL && indsp->enabled) {
08459 StringID strid;
08460
08461
08462
08463 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
08464 if (strid != STR_UNDEFINED) indsp->name = strid;
08465
08466 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
08467 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
08468
08469 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
08470 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
08471
08472 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
08473 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
08474
08475 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
08476 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
08477
08478 if (indsp->station_name != STR_NULL) {
08479
08480
08481 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
08482 if (strid != STR_UNDEFINED) indsp->station_name = strid;
08483 }
08484
08485 _industry_mngr.SetEntitySpec(indsp);
08486 _loaded_newgrf_features.has_newindustries = true;
08487 }
08488 }
08489 }
08490
08491 if (indtspec != NULL) {
08492 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
08493 IndustryTileSpec *indtsp = indtspec[i];
08494 if (indtsp != NULL) {
08495 _industile_mngr.SetEntitySpec(indtsp);
08496 }
08497 }
08498 }
08499 }
08500
08501 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
08502 IndustrySpec *indsp = &_industry_specs[j];
08503 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
08504 for (uint i = 0; i < 3; i++) {
08505 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
08506 }
08507 }
08508 if (!indsp->enabled) {
08509 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
08510 }
08511 }
08512 }
08513
08519 static void FinaliseObjectsArray()
08520 {
08521 const GRFFile * const *end = _grf_files.End();
08522 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08523 ObjectSpec **&objectspec = (*file)->objectspec;
08524 if (objectspec != NULL) {
08525 for (int i = 0; i < NUM_OBJECTS; i++) {
08526 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
08527 _object_mngr.SetEntitySpec(objectspec[i]);
08528 }
08529 }
08530 }
08531 }
08532 }
08533
08539 static void FinaliseAirportsArray()
08540 {
08541 const GRFFile * const *end = _grf_files.End();
08542 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08543 AirportSpec **&airportspec = (*file)->airportspec;
08544 if (airportspec != NULL) {
08545 for (int i = 0; i < NUM_AIRPORTS; i++) {
08546 if (airportspec[i] != NULL && airportspec[i]->enabled) {
08547 _airport_mngr.SetEntitySpec(airportspec[i]);
08548 }
08549 }
08550 }
08551
08552 AirportTileSpec **&airporttilespec = (*file)->airtspec;
08553 if (airporttilespec != NULL) {
08554 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
08555 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
08556 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
08557 }
08558 }
08559 }
08560 }
08561 }
08562
08563
08564
08565
08566
08567
08568
08569 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
08570 {
08571
08572
08573
08574
08575
08576
08577
08578
08579
08580
08581
08582
08583 static const SpecialSpriteHandler handlers[][GLS_END] = {
08584 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
08585 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
08586 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
08587 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
08588 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
08589 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
08590 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
08591 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
08592 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
08593 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
08594 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
08595 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
08596 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
08597 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
08598 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
08599 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
08600 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
08601 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
08602 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
08603 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
08604 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
08605 };
08606
08607 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
08608
08609 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
08610 if (it == _grf_line_to_action6_sprite_override.end()) {
08611
08612
08613 FioReadBlock(buf, num);
08614 } else {
08615
08616 buf = _grf_line_to_action6_sprite_override[location];
08617 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
08618
08619
08620 FioSeekTo(num, SEEK_CUR);
08621 }
08622
08623 ByteReader br(buf, buf + num);
08624 ByteReader *bufp = &br;
08625
08626 try {
08627 byte action = bufp->ReadByte();
08628
08629 if (action == 0xFF) {
08630 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
08631 GRFDataBlock(bufp);
08632 } else if (action == 0xFE) {
08633 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
08634 GRFImportBlock(bufp);
08635 } else if (action >= lengthof(handlers)) {
08636 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
08637 } else if (handlers[action][stage] == NULL) {
08638 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
08639 } else {
08640 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
08641 handlers[action][stage](bufp);
08642 }
08643 } catch (...) {
08644 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
08645 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
08646 }
08647 }
08648
08649
08657 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
08658 {
08659 const char *filename = config->filename;
08660 uint16 num;
08661
08662
08663
08664
08665
08666
08667
08668
08669
08670
08671 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
08672 _cur.grffile = GetFileByFilename(filename);
08673 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
08674 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
08675 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
08676 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
08677 }
08678
08679 if (file_index > LAST_GRF_SLOT) {
08680 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
08681 config->status = GCS_DISABLED;
08682 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
08683 return;
08684 }
08685
08686 FioOpenFile(file_index, filename, subdir);
08687 _cur.file_index = file_index;
08688 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
08689
08690 _cur.grfconfig = config;
08691
08692 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
08693
08694
08695
08696
08697 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
08698 FioReadDword();
08699 } else {
08700 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
08701 return;
08702 }
08703
08704 _cur.ClearDataForNextFile();
08705
08706 ReusableBuffer<byte> buf;
08707
08708 while ((num = FioReadWord()) != 0) {
08709 byte type = FioReadByte();
08710 _cur.nfo_line++;
08711
08712 if (type == 0xFF) {
08713 if (_cur.skip_sprites == 0) {
08714 DecodeSpecialSprite(buf.Allocate(num), num, stage);
08715
08716
08717 if (_cur.skip_sprites == -1) break;
08718
08719 continue;
08720 } else {
08721 FioSkipBytes(num);
08722 }
08723 } else {
08724 if (_cur.skip_sprites == 0) {
08725 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08726 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08727 break;
08728 }
08729
08730 FioSkipBytes(7);
08731 SkipSpriteData(type, num - 8);
08732 }
08733
08734 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
08735 }
08736 }
08737
08745 static void ActivateOldShore()
08746 {
08747
08748
08749 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08750
08751 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08752 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08753 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08754 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08755 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08756 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08757 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08758 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08759 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08760 }
08761
08762 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08763 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08764 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08765 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08766 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08767 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08768 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08769 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08770 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08771
08772
08773
08774 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08775 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08776 }
08777 }
08778
08782 static void FinalisePriceBaseMultipliers()
08783 {
08784 extern const PriceBaseSpec _price_base_specs[];
08786 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08787
08788
08789 int num_grfs = _grf_files.Length();
08790 int *grf_overrides = AllocaM(int, num_grfs);
08791 for (int i = 0; i < num_grfs; i++) {
08792 grf_overrides[i] = -1;
08793
08794 GRFFile *source = _grf_files[i];
08795 uint32 override = _grf_id_overrides[source->grfid];
08796 if (override == 0) continue;
08797
08798 GRFFile *dest = GetFileByGRFID(override);
08799 if (dest == NULL) continue;
08800
08801 grf_overrides[i] = _grf_files.FindIndex(dest);
08802 assert(grf_overrides[i] >= 0);
08803 }
08804
08805
08806 for (int i = 0; i < num_grfs; i++) {
08807 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08808 GRFFile *source = _grf_files[i];
08809 GRFFile *dest = _grf_files[grf_overrides[i]];
08810
08811 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08812 source->grf_features |= features;
08813 dest->grf_features |= features;
08814
08815 for (Price p = PR_BEGIN; p < PR_END; p++) {
08816
08817 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08818 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08819 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08820 }
08821 }
08822
08823
08824 for (int i = num_grfs - 1; i >= 0; i--) {
08825 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08826 GRFFile *source = _grf_files[i];
08827 GRFFile *dest = _grf_files[grf_overrides[i]];
08828
08829 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08830 source->grf_features |= features;
08831 dest->grf_features |= features;
08832
08833 for (Price p = PR_BEGIN; p < PR_END; p++) {
08834
08835 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08836 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08837 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08838 }
08839 }
08840
08841
08842 for (int i = 0; i < num_grfs; i++) {
08843 if (grf_overrides[i] < 0) continue;
08844 GRFFile *source = _grf_files[i];
08845 GRFFile *dest = _grf_files[grf_overrides[i]];
08846
08847 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08848 source->grf_features |= features;
08849 dest->grf_features |= features;
08850
08851 for (Price p = PR_BEGIN; p < PR_END; p++) {
08852 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08853 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08854 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08855 }
08856 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08857 }
08858 }
08859
08860
08861 const GRFFile * const *end = _grf_files.End();
08862 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08863 if ((*file)->grf_version >= 8) continue;
08864 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08865 for (Price p = PR_BEGIN; p < PR_END; p++) {
08866 Price fallback_price = _price_base_specs[p].fallback_price;
08867 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08868
08869
08870 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08871 }
08872 }
08873 }
08874
08875
08876 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08877 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08878 for (Price p = PR_BEGIN; p < PR_END; p++) {
08879 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08880
08881 price_base_multipliers[p] = 0;
08882 } else {
08883 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08884
08885
08886 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08887 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08888 price_base_multipliers[p] = 0;
08889 } else {
08890 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08891 }
08892 }
08893 }
08894 }
08895 }
08896
08897 void InitDepotWindowBlockSizes();
08898
08899 extern void InitGRFTownGeneratorNames();
08900
08902 static void AfterLoadGRFs()
08903 {
08904 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08905 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08906 }
08907 _string_to_grf_mapping.clear();
08908
08909
08910 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08911 free((*it).second);
08912 }
08913 _grf_line_to_action6_sprite_override.clear();
08914
08915
08916 FinaliseCargoArray();
08917
08918
08919 CalculateRefitMasks();
08920
08921
08922 FinaliseEngineArray();
08923
08924
08925 FinaliseCanals();
08926
08927
08928 InitDepotWindowBlockSizes();
08929
08930
08931 FinaliseHouseArray();
08932
08933
08934 FinaliseIndustriesArray();
08935
08936
08937 FinaliseObjectsArray();
08938
08939 InitializeSortedCargoSpecs();
08940
08941
08942 SortIndustryTypes();
08943
08944
08945 BuildIndustriesLegend();
08946
08947
08948 FinaliseAirportsArray();
08949 BindAirportSpecs();
08950
08951
08952 InitGRFTownGeneratorNames();
08953
08954
08955 CommitVehicleListOrderChanges();
08956
08957
08958 ActivateOldShore();
08959
08960
08961 InitRailTypes();
08962
08963 Engine *e;
08964 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
08965 if (_gted[e->index].rv_max_speed != 0) {
08966
08967 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
08968 }
08969 }
08970
08971 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
08972 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
08973 if (railtype == INVALID_RAILTYPE) {
08974
08975 e->info.climates = 0;
08976 } else {
08977 e->u.rail.railtype = railtype;
08978 }
08979 }
08980
08981 SetYearEngineAgingStops();
08982
08983 FinalisePriceBaseMultipliers();
08984
08985
08986 free(_gted);
08987 _grm_sprites.clear();
08988 }
08989
08995 void LoadNewGRF(uint load_index, uint file_index)
08996 {
08997
08998
08999
09000
09001 Date date = _date;
09002 Year year = _cur_year;
09003 DateFract date_fract = _date_fract;
09004 uint16 tick_counter = _tick_counter;
09005 byte display_opt = _display_opt;
09006
09007 if (_networking) {
09008 _cur_year = _settings_game.game_creation.starting_year;
09009 _date = ConvertYMDToDate(_cur_year, 0, 1);
09010 _date_fract = 0;
09011 _tick_counter = 0;
09012 _display_opt = 0;
09013 }
09014
09015 InitializeGRFSpecial();
09016
09017 ResetNewGRFData();
09018
09019
09020
09021
09022
09023
09024
09025
09026 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09027 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
09028 }
09029
09030 _cur.spriteid = load_index;
09031
09032
09033
09034
09035 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
09036
09037
09038 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09039 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
09040 }
09041
09042 if (stage == GLS_RESERVE) {
09043 static const uint32 overrides[][2] = {
09044 { 0x44442202, 0x44440111 },
09045 { 0x6D620402, 0x6D620401 },
09046 { 0x4D656f20, 0x4D656F17 },
09047 };
09048 for (size_t i = 0; i < lengthof(overrides); i++) {
09049 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
09050 }
09051 }
09052
09053 uint slot = file_index;
09054
09055 _cur.stage = stage;
09056 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
09057 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
09058 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
09059
09060 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
09061 if (!FioCheckFileExists(c->filename, subdir)) {
09062 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
09063 c->status = GCS_NOT_FOUND;
09064 continue;
09065 }
09066
09067 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
09068 LoadNewGRFFile(c, slot++, stage, subdir);
09069 if (stage == GLS_RESERVE) {
09070 SetBit(c->flags, GCF_RESERVED);
09071 } else if (stage == GLS_ACTIVATION) {
09072 ClrBit(c->flags, GCF_RESERVED);
09073 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
09074 ClearTemporaryNewGRFData(_cur.grffile);
09075 BuildCargoTranslationMap();
09076 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
09077 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
09078
09079 ClearTemporaryNewGRFData(_cur.grffile);
09080 }
09081 }
09082 }
09083
09084
09085 _cur.ClearDataForNextFile();
09086
09087
09088 AfterLoadGRFs();
09089
09090
09091 _cur_year = year;
09092 _date = date;
09093 _date_fract = date_fract;
09094 _tick_counter = tick_counter;
09095 _display_opt = display_opt;
09096 }