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