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