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