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