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