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