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