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