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