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