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 "variables.h"
00021 #include "bridge.h"
00022 #include "town.h"
00023 #include "newgrf_engine.h"
00024 #include "newgrf_text.h"
00025 #include "fontcache.h"
00026 #include "currency.h"
00027 #include "landscape.h"
00028 #include "newgrf.h"
00029 #include "newgrf_cargo.h"
00030 #include "newgrf_house.h"
00031 #include "newgrf_sound.h"
00032 #include "newgrf_station.h"
00033 #include "industry.h"
00034 #include "newgrf_canal.h"
00035 #include "newgrf_commons.h"
00036 #include "newgrf_townname.h"
00037 #include "newgrf_industries.h"
00038 #include "rev.h"
00039 #include "fios.h"
00040 #include "rail.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 "core/alloc_type.hpp"
00047 #include "core/mem_func.hpp"
00048 #include "smallmap_gui.h"
00049
00050 #include "table/strings.h"
00051 #include "table/build_industry.h"
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 static int _skip_sprites;
00064 static uint _file_index;
00065
00066 static SmallVector<GRFFile *, 16> _grf_files;
00067
00068 static GRFFile *_cur_grffile;
00069 static SpriteID _cur_spriteid;
00070 static GrfLoadingStage _cur_stage;
00071 static uint32 _nfo_line;
00072
00073 static GRFConfig *_cur_grfconfig;
00074
00075
00076 static byte _misc_grf_features = 0;
00077
00078
00079 static uint32 _ttdpatch_flags[8];
00080
00081
00082 GRFLoadedFeatures _loaded_newgrf_features;
00083
00084 enum GrfDataType {
00085 GDT_SOUND,
00086 };
00087
00088 static byte _grf_data_blocks;
00089 static GrfDataType _grf_data_type;
00090
00091 class OTTDByteReaderSignal { };
00092
00093 class ByteReader {
00094 protected:
00095 byte *data;
00096 byte *end;
00097
00098 public:
00099 ByteReader(byte *data, byte *end) : data(data), end(end) { }
00100
00101 FORCEINLINE byte ReadByte()
00102 {
00103 if (data < end) return *(data)++;
00104 throw OTTDByteReaderSignal();
00105 }
00106
00107 uint16 ReadWord()
00108 {
00109 uint16 val = ReadByte();
00110 return val | (ReadByte() << 8);
00111 }
00112
00113 uint16 ReadExtended()
00114 {
00115 uint16 val = ReadByte();
00116 return val == 0xFF ? ReadWord() : val;
00117 }
00118
00119 uint32 ReadDWord()
00120 {
00121 uint32 val = ReadWord();
00122 return val | (ReadWord() << 16);
00123 }
00124
00125 uint32 ReadVarSize(byte size)
00126 {
00127 switch (size) {
00128 case 1: return ReadByte();
00129 case 2: return ReadWord();
00130 case 4: return ReadDWord();
00131 default:
00132 NOT_REACHED();
00133 return 0;
00134 }
00135 }
00136
00137 const char *ReadString()
00138 {
00139 char *string = reinterpret_cast<char *>(data);
00140 size_t string_length = ttd_strnlen(string, Remaining());
00141
00142 if (string_length == Remaining()) {
00143
00144 string[string_length - 1] = '\0';
00145 grfmsg(7, "String was not terminated with a zero byte.");
00146 } else {
00147
00148 string_length++;
00149 }
00150 Skip(string_length);
00151
00152 return string;
00153 }
00154
00155 FORCEINLINE size_t Remaining() const
00156 {
00157 return end - data;
00158 }
00159
00160 FORCEINLINE bool HasData() const
00161 {
00162 return data < end;
00163 }
00164
00165 FORCEINLINE byte *Data()
00166 {
00167 return data;
00168 }
00169
00170 FORCEINLINE void Skip(size_t len)
00171 {
00172 data += len;
00173
00174
00175 if (data > end) throw OTTDByteReaderSignal();
00176 }
00177 };
00178
00179 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
00180
00181 enum {
00182 MAX_STATIONS = 256,
00183 };
00184
00185
00186 struct GRFTempEngineData {
00187 uint16 cargo_allowed;
00188 uint16 cargo_disallowed;
00189 bool refitmask_valid;
00190 uint8 rv_max_speed;
00191 };
00192
00193 static GRFTempEngineData *_gted;
00194
00195
00196
00197
00198 static uint32 _grm_engines[256];
00199
00200
00201 static uint32 _grm_cargos[NUM_CARGO * 2];
00202
00203 struct GRFLocation {
00204 uint32 grfid;
00205 uint32 nfoline;
00206
00207 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
00208
00209 bool operator<(const GRFLocation &other) const
00210 {
00211 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
00212 }
00213
00214 bool operator == (const GRFLocation &other) const
00215 {
00216 return this->grfid == other.grfid && this->nfoline == other.nfoline;
00217 }
00218 };
00219
00220 static std::map<GRFLocation, SpriteID> _grm_sprites;
00221 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
00222 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
00223
00232 void CDECL grfmsg(int severity, const char *str, ...)
00233 {
00234 char buf[1024];
00235 va_list va;
00236
00237 va_start(va, str);
00238 vsnprintf(buf, sizeof(buf), str, va);
00239 va_end(va);
00240
00241 DEBUG(grf, severity, "[%s:%d] %s", _cur_grfconfig->filename, _nfo_line, buf);
00242 }
00243
00244 static GRFFile *GetFileByGRFID(uint32 grfid)
00245 {
00246 const GRFFile * const *end = _grf_files.End();
00247 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00248 if ((*file)->grfid == grfid) return *file;
00249 }
00250 return NULL;
00251 }
00252
00253 static GRFFile *GetFileByFilename(const char *filename)
00254 {
00255 const GRFFile * const *end = _grf_files.End();
00256 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
00257 if (strcmp((*file)->filename, filename) == 0) return *file;
00258 }
00259 return NULL;
00260 }
00261
00263 static void ClearTemporaryNewGRFData(GRFFile *gf)
00264 {
00265
00266 for (GRFLabel *l = gf->label; l != NULL;) {
00267 GRFLabel *l2 = l->next;
00268 free(l);
00269 l = l2;
00270 }
00271 gf->label = NULL;
00272
00273
00274 free(gf->spritegroups);
00275 gf->spritegroups = NULL;
00276 gf->spritegroups_count = 0;
00277 }
00278
00279
00280 typedef std::map<StringID *, uint32> StringIDToGRFIDMapping;
00281 static StringIDToGRFIDMapping _string_to_grf_mapping;
00282
00289 StringID MapGRFStringID(uint32 grfid, StringID str)
00290 {
00291
00292
00293
00294
00295 switch (GB(str, 8, 8)) {
00296 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
00297 case 0xDC:
00298 return GetGRFStringID(grfid, str);
00299
00300 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
00301
00302
00303 return GetGRFStringID(grfid, str - 0x400);
00304
00305 default: break;
00306 }
00307
00308 return TTDPStringIDToOTTDStringIDMapping(str);
00309 }
00310
00311 static inline uint8 MapDOSColour(uint8 colour)
00312 {
00313 extern const byte _palmap_d2w[];
00314 return (_use_palette == PAL_DOS ? colour : _palmap_d2w[colour]);
00315 }
00316
00317 static std::map<uint32, uint32> _grf_id_overrides;
00318
00319 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
00320 {
00321 _grf_id_overrides[source_grfid] = target_grfid;
00322 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
00323 }
00324
00333 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
00334 {
00335
00336
00337 uint32 scope_grfid = INVALID_GRFID;
00338 if (_settings_game.vehicle.dynamic_engines) {
00339
00340 scope_grfid = file->grfid;
00341 uint32 override = _grf_id_overrides[file->grfid];
00342 if (override != 0) {
00343 scope_grfid = override;
00344 const GRFFile *grf_match = GetFileByGRFID(override);
00345 if (grf_match == NULL) {
00346 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
00347 } else {
00348 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
00349 }
00350 }
00351
00352
00353 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
00354 if (engine != INVALID_ENGINE) {
00355 Engine *e = Engine::Get(engine);
00356 if (e->grffile == NULL) e->grffile = file;
00357 return e;
00358 }
00359 }
00360
00361
00362 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
00363 if (engine != INVALID_ENGINE) {
00364 Engine *e = Engine::Get(engine);
00365
00366 if (e->grffile == NULL) {
00367 e->grffile = file;
00368 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00369 }
00370
00371
00372 if (!static_access) {
00373 EngineIDMapping *eid = _engine_mngr.Get(engine);
00374 eid->grfid = scope_grfid;
00375 }
00376
00377 return e;
00378 }
00379
00380 if (static_access) return NULL;
00381
00382 size_t engine_pool_size = Engine::GetPoolSize();
00383
00384
00385 Engine *e = new Engine(type, internal_id);
00386 e->grffile = file;
00387
00388
00389 assert(_engine_mngr.Length() == e->index);
00390 EngineIDMapping *eid = _engine_mngr.Append();
00391 eid->type = type;
00392 eid->grfid = scope_grfid;
00393 eid->internal_id = internal_id;
00394 eid->substitute_id = min(internal_id, _engine_counts[type]);
00395
00396 if (engine_pool_size != Engine::GetPoolSize()) {
00397
00398 _gted = ReallocT(_gted, Engine::GetPoolSize());
00399
00400
00401 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
00402 memset(_gted + engine_pool_size, 0, len);
00403 }
00404
00405 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
00406
00407 return e;
00408 }
00409
00410 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
00411 {
00412 uint32 scope_grfid = INVALID_GRFID;
00413 if (_settings_game.vehicle.dynamic_engines) {
00414 scope_grfid = file->grfid;
00415 uint32 override = _grf_id_overrides[file->grfid];
00416 if (override != 0) scope_grfid = override;
00417 }
00418
00419 return _engine_mngr.GetID(type, internal_id, scope_grfid);
00420 }
00421
00425 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
00426 {
00427 if (HasBit(grf_sprite->pal, 14)) {
00428 ClrBit(grf_sprite->pal, 14);
00429 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
00430 }
00431
00432 if (HasBit(grf_sprite->sprite, 14)) {
00433 ClrBit(grf_sprite->sprite, 14);
00434 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
00435 }
00436
00437 if (HasBit(grf_sprite->sprite, 15)) {
00438 ClrBit(grf_sprite->sprite, 15);
00439 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
00440 }
00441 }
00442
00450 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
00451 {
00452
00453 if (base_pointer == 0) {
00454 *index = INVALID_PRICE;
00455 return;
00456 }
00457
00458 static const uint32 start = 0x4B34;
00459 static const uint32 size = 6;
00460
00461 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
00462 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
00463 return;
00464 }
00465
00466 *index = (Price)((base_pointer - start) / size);
00467 }
00468
00469 enum ChangeInfoResult {
00470 CIR_SUCCESS,
00471 CIR_UNHANDLED,
00472 CIR_UNKNOWN,
00473 CIR_INVALID_ID,
00474 };
00475
00476 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
00477
00478 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
00479 {
00480 switch (prop) {
00481 case 0x00:
00482 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
00483 break;
00484
00485 case 0x02:
00486 ei->decay_speed = buf->ReadByte();
00487 break;
00488
00489 case 0x03:
00490 ei->lifelength = buf->ReadByte();
00491 break;
00492
00493 case 0x04:
00494 ei->base_life = buf->ReadByte();
00495 break;
00496
00497 case 0x06:
00498 ei->climates = buf->ReadByte();
00499
00500
00501 if (ei->climates == 0) ei->climates = 0x80;
00502 break;
00503
00504 case 0x07:
00505
00506 ei->load_amount = buf->ReadByte();
00507 break;
00508
00509 default:
00510 return CIR_UNKNOWN;
00511 }
00512
00513 return CIR_SUCCESS;
00514 }
00515
00516 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00517 {
00518 ChangeInfoResult ret = CIR_SUCCESS;
00519
00520 for (int i = 0; i < numinfo; i++) {
00521 Engine *e = GetNewEngine(_cur_grffile, VEH_TRAIN, engine + i);
00522 EngineInfo *ei = &e->info;
00523 RailVehicleInfo *rvi = &e->u.rail;
00524
00525 switch (prop) {
00526 case 0x05: {
00527 uint8 tracktype = buf->ReadByte();
00528
00529 if (tracktype < _cur_grffile->railtype_max) {
00530 RailType railtype = GetRailTypeByLabel(_cur_grffile->railtype_list[tracktype]);
00531 if (railtype == INVALID_RAILTYPE) {
00532
00533 ei[i].climates = 0x80;
00534 } else {
00535 rvi[i].railtype = railtype;
00536 }
00537 break;
00538 }
00539
00540 switch (tracktype) {
00541 case 0: rvi->railtype = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break;
00542 case 1: rvi->railtype = RAILTYPE_MONO; break;
00543 case 2: rvi->railtype = RAILTYPE_MAGLEV; break;
00544 default:
00545 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
00546 break;
00547 }
00548 } break;
00549
00550 case 0x08:
00551
00552
00553 rvi->ai_passenger_only = buf->ReadByte();
00554 break;
00555
00556 case PROP_TRAIN_SPEED: {
00557 uint16 speed = buf->ReadWord();
00558 if (speed == 0xFFFF) speed = 0;
00559
00560 rvi->max_speed = speed;
00561 } break;
00562
00563 case PROP_TRAIN_POWER:
00564 rvi->power = buf->ReadWord();
00565
00566
00567 if (rvi->power != 0) {
00568 if (rvi->railveh_type == RAILVEH_WAGON) {
00569 rvi->railveh_type = RAILVEH_SINGLEHEAD;
00570 }
00571 } else {
00572 rvi->railveh_type = RAILVEH_WAGON;
00573 }
00574 break;
00575
00576 case PROP_TRAIN_RUNNING_COST_FACTOR:
00577 rvi->running_cost = buf->ReadByte();
00578 break;
00579
00580 case 0x0E:
00581 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
00582 break;
00583
00584 case 0x12: {
00585 uint8 spriteid = buf->ReadByte();
00586
00587
00588
00589 if (spriteid < 0xFD) spriteid >>= 1;
00590
00591 rvi->image_index = spriteid;
00592 } break;
00593
00594 case 0x13: {
00595 uint8 dual = buf->ReadByte();
00596
00597 if (dual != 0) {
00598 rvi->railveh_type = RAILVEH_MULTIHEAD;
00599 } else {
00600 rvi->railveh_type = rvi->power == 0 ?
00601 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
00602 }
00603 } break;
00604
00605 case PROP_TRAIN_CARGO_CAPACITY:
00606 rvi->capacity = buf->ReadByte();
00607 break;
00608
00609 case 0x15: {
00610 uint8 ctype = buf->ReadByte();
00611
00612 if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
00613 ei->cargo_type = ctype;
00614 } else if (ctype == 0xFF) {
00615
00616 ei->cargo_type = CT_INVALID;
00617 } else {
00618 ei->cargo_type = CT_INVALID;
00619 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
00620 }
00621 } break;
00622
00623 case PROP_TRAIN_WEIGHT:
00624 SB(rvi->weight, 0, 8, buf->ReadByte());
00625 break;
00626
00627 case PROP_TRAIN_COST_FACTOR:
00628 rvi->cost_factor = buf->ReadByte();
00629 break;
00630
00631 case 0x18:
00632 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
00633 buf->ReadByte();
00634 break;
00635
00636 case 0x19: {
00637
00638
00639
00640
00641
00642
00643
00644 uint8 traction = buf->ReadByte();
00645 EngineClass engclass;
00646
00647 if (traction <= 0x07) {
00648 engclass = EC_STEAM;
00649 } else if (traction <= 0x27) {
00650 engclass = EC_DIESEL;
00651 } else if (traction <= 0x31) {
00652 engclass = EC_ELECTRIC;
00653 } else if (traction <= 0x37) {
00654 engclass = EC_MONORAIL;
00655 } else if (traction <= 0x41) {
00656 engclass = EC_MAGLEV;
00657 } else {
00658 break;
00659 }
00660
00661 if (_cur_grffile->railtype_max == 0) {
00662
00663
00664 if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi->railtype = RAILTYPE_ELECTRIC;
00665 if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi->railtype = RAILTYPE_RAIL;
00666 }
00667
00668 rvi->engclass = engclass;
00669 } break;
00670
00671 case 0x1A:
00672 AlterVehicleListOrder(e->index, buf->ReadExtended());
00673 break;
00674
00675 case 0x1B:
00676 rvi->pow_wag_power = buf->ReadWord();
00677 break;
00678
00679 case 0x1C:
00680 ei->refit_cost = buf->ReadByte();
00681 break;
00682
00683 case 0x1D:
00684 ei->refit_mask = buf->ReadDWord();
00685 _gted[e->index].refitmask_valid = true;
00686 break;
00687
00688 case 0x1E:
00689 ei->callback_mask = buf->ReadByte();
00690 break;
00691
00692 case PROP_TRAIN_TRACTIVE_EFFORT:
00693 rvi->tractive_effort = buf->ReadByte();
00694 break;
00695
00696 case 0x20:
00698 buf->ReadByte();
00699 ret = CIR_UNHANDLED;
00700 break;
00701
00702 case 0x21:
00703 rvi->shorten_factor = buf->ReadByte();
00704 break;
00705
00706 case 0x22:
00708 rvi->visual_effect = buf->ReadByte();
00709 break;
00710
00711 case 0x23:
00712 rvi->pow_wag_weight = buf->ReadByte();
00713 break;
00714
00715 case 0x24: {
00716 byte weight = buf->ReadByte();
00717
00718 if (weight > 4) {
00719 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
00720 } else {
00721 SB(rvi->weight, 8, 8, weight);
00722 }
00723 } break;
00724
00725 case PROP_TRAIN_USER_DATA:
00726 rvi->user_def_data = buf->ReadByte();
00727 break;
00728
00729 case 0x26:
00730 ei->retire_early = buf->ReadByte();
00731 break;
00732
00733 case 0x27:
00734 ei->misc_flags = buf->ReadByte();
00735 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00736 break;
00737
00738 case 0x28:
00739 _gted[e->index].cargo_allowed = buf->ReadWord();
00740 _gted[e->index].refitmask_valid = true;
00741 break;
00742
00743 case 0x29:
00744 _gted[e->index].cargo_disallowed = buf->ReadWord();
00745 _gted[e->index].refitmask_valid = true;
00746 break;
00747
00748 case 0x2A:
00749 ei->base_intro = buf->ReadDWord();
00750 break;
00751
00752 default:
00753 ret = CommonVehicleChangeInfo(ei, prop, buf);
00754 break;
00755 }
00756 }
00757
00758 return ret;
00759 }
00760
00761 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00762 {
00763 ChangeInfoResult ret = CIR_SUCCESS;
00764
00765 for (int i = 0; i < numinfo; i++) {
00766 Engine *e = GetNewEngine(_cur_grffile, VEH_ROAD, engine + i);
00767 EngineInfo *ei = &e->info;
00768 RoadVehicleInfo *rvi = &e->u.road;
00769
00770 switch (prop) {
00771 case 0x08:
00772 rvi->max_speed = buf->ReadByte();
00773 break;
00774
00775 case PROP_ROADVEH_RUNNING_COST_FACTOR:
00776 rvi->running_cost = buf->ReadByte();
00777 break;
00778
00779 case 0x0A:
00780 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
00781 break;
00782
00783 case 0x0E: {
00784 uint8 spriteid = buf->ReadByte();
00785
00786
00787 if (spriteid == 0xFF) spriteid = 0xFD;
00788
00789 if (spriteid < 0xFD) spriteid >>= 1;
00790
00791 rvi->image_index = spriteid;
00792 } break;
00793
00794 case PROP_ROADVEH_CARGO_CAPACITY:
00795 rvi->capacity = buf->ReadByte();
00796 break;
00797
00798 case 0x10: {
00799 uint8 cargo = buf->ReadByte();
00800
00801 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
00802 ei->cargo_type = cargo;
00803 } else if (cargo == 0xFF) {
00804 ei->cargo_type = CT_INVALID;
00805 } else {
00806 ei->cargo_type = CT_INVALID;
00807 grfmsg(2, "RoadVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
00808 }
00809 } break;
00810
00811 case PROP_ROADVEH_COST_FACTOR:
00812 rvi->cost_factor = buf->ReadByte();
00813 break;
00814
00815 case 0x12:
00816 rvi->sfx = buf->ReadByte();
00817 break;
00818
00819 case 0x13:
00820 rvi->power = buf->ReadByte();
00821 break;
00822
00823 case 0x14:
00824 rvi->weight = buf->ReadByte();
00825 break;
00826
00827 case 0x15:
00828 _gted[e->index].rv_max_speed = buf->ReadByte();
00829 break;
00830
00831 case 0x16:
00832 ei->refit_mask = buf->ReadDWord();
00833 _gted[e->index].refitmask_valid = true;
00834 break;
00835
00836 case 0x17:
00837 ei->callback_mask = buf->ReadByte();
00838 break;
00839
00840 case 0x18:
00841 rvi->tractive_effort = buf->ReadByte();
00842 break;
00843
00844 case 0x19:
00845 rvi->air_drag = buf->ReadByte();
00846 break;
00847
00848 case 0x1A:
00849 ei->refit_cost = buf->ReadByte();
00850 break;
00851
00852 case 0x1B:
00853 ei->retire_early = buf->ReadByte();
00854 break;
00855
00856 case 0x1C:
00857 ei->misc_flags = buf->ReadByte();
00858 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00859 break;
00860
00861 case 0x1D:
00862 _gted[e->index].cargo_allowed = buf->ReadWord();
00863 _gted[e->index].refitmask_valid = true;
00864 break;
00865
00866 case 0x1E:
00867 _gted[e->index].cargo_disallowed = buf->ReadWord();
00868 _gted[e->index].refitmask_valid = true;
00869 break;
00870
00871 case 0x1F:
00872 ei->base_intro = buf->ReadDWord();
00873 break;
00874
00875 case 0x20:
00876 AlterVehicleListOrder(e->index, buf->ReadExtended());
00877 break;
00878
00879 default:
00880 ret = CommonVehicleChangeInfo(ei, prop, buf);
00881 break;
00882 }
00883 }
00884
00885 return ret;
00886 }
00887
00888 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
00889 {
00890 ChangeInfoResult ret = CIR_SUCCESS;
00891
00892 for (int i = 0; i < numinfo; i++) {
00893 Engine *e = GetNewEngine(_cur_grffile, VEH_SHIP, engine + i);
00894 EngineInfo *ei = &e->info;
00895 ShipVehicleInfo *svi = &e->u.ship;
00896
00897 switch (prop) {
00898 case 0x08: {
00899 uint8 spriteid = buf->ReadByte();
00900
00901
00902 if (spriteid == 0xFF) spriteid = 0xFD;
00903
00904 if (spriteid < 0xFD) spriteid >>= 1;
00905
00906 svi->image_index = spriteid;
00907 } break;
00908
00909 case 0x09:
00910 svi->old_refittable = (buf->ReadByte() != 0);
00911 break;
00912
00913 case PROP_SHIP_COST_FACTOR:
00914 svi->cost_factor = buf->ReadByte();
00915 break;
00916
00917 case PROP_SHIP_SPEED:
00918 svi->max_speed = buf->ReadByte();
00919 break;
00920
00921 case 0x0C: {
00922 uint8 cargo = buf->ReadByte();
00923
00924 if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
00925 ei->cargo_type = cargo;
00926 } else if (cargo == 0xFF) {
00927 ei->cargo_type = CT_INVALID;
00928 } else {
00929 ei->cargo_type = CT_INVALID;
00930 grfmsg(2, "ShipVehicleChangeInfo: Invalid cargo type %d, using first refittable", cargo);
00931 }
00932 } break;
00933
00934 case PROP_SHIP_CARGO_CAPACITY:
00935 svi->capacity = buf->ReadWord();
00936 break;
00937
00938 case PROP_SHIP_RUNNING_COST_FACTOR:
00939 svi->running_cost = buf->ReadByte();
00940 break;
00941
00942 case 0x10:
00943 svi->sfx = buf->ReadByte();
00944 break;
00945
00946 case 0x11:
00947 ei->refit_mask = buf->ReadDWord();
00948 _gted[e->index].refitmask_valid = true;
00949 break;
00950
00951 case 0x12:
00952 ei->callback_mask = buf->ReadByte();
00953 break;
00954
00955 case 0x13:
00956 ei->refit_cost = buf->ReadByte();
00957 break;
00958
00959 case 0x14:
00960 case 0x15:
00962 buf->ReadByte();
00963 ret = CIR_UNHANDLED;
00964 break;
00965
00966 case 0x16:
00967 ei->retire_early = buf->ReadByte();
00968 break;
00969
00970 case 0x17:
00971 ei->misc_flags = buf->ReadByte();
00972 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
00973 break;
00974
00975 case 0x18:
00976 _gted[e->index].cargo_allowed = buf->ReadWord();
00977 _gted[e->index].refitmask_valid = true;
00978 break;
00979
00980 case 0x19:
00981 _gted[e->index].cargo_disallowed = buf->ReadWord();
00982 _gted[e->index].refitmask_valid = true;
00983 break;
00984
00985 case 0x1A:
00986 ei->base_intro = buf->ReadDWord();
00987 break;
00988
00989 case 0x1B:
00990 AlterVehicleListOrder(e->index, buf->ReadExtended());
00991 break;
00992
00993 default:
00994 ret = CommonVehicleChangeInfo(ei, prop, buf);
00995 break;
00996 }
00997 }
00998
00999 return ret;
01000 }
01001
01002 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
01003 {
01004 ChangeInfoResult ret = CIR_SUCCESS;
01005
01006 for (int i = 0; i < numinfo; i++) {
01007 Engine *e = GetNewEngine(_cur_grffile, VEH_AIRCRAFT, engine + i);
01008 EngineInfo *ei = &e->info;
01009 AircraftVehicleInfo *avi = &e->u.air;
01010
01011 switch (prop) {
01012 case 0x08: {
01013 uint8 spriteid = buf->ReadByte();
01014
01015
01016 if (spriteid == 0xFF) spriteid = 0xFD;
01017
01018 if (spriteid < 0xFD) spriteid >>= 1;
01019
01020 avi->image_index = spriteid;
01021 } break;
01022
01023 case 0x09:
01024 if (buf->ReadByte() == 0) {
01025 avi->subtype = AIR_HELI;
01026 } else {
01027 SB(avi->subtype, 0, 1, 1);
01028 }
01029 break;
01030
01031 case 0x0A:
01032 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
01033 break;
01034
01035 case PROP_AIRCRAFT_COST_FACTOR:
01036 avi->cost_factor = buf->ReadByte();
01037 break;
01038
01039 case PROP_AIRCRAFT_SPEED:
01040 avi->max_speed = (buf->ReadByte() * 129) / 10;
01041 break;
01042
01043 case 0x0D:
01044 avi->acceleration = (buf->ReadByte() * 129) / 10;
01045 break;
01046
01047 case PROP_AIRCRAFT_RUNNING_COST_FACTOR:
01048 avi->running_cost = buf->ReadByte();
01049 break;
01050
01051 case 0x0F:
01052 avi->passenger_capacity = buf->ReadWord();
01053 break;
01054
01055 case 0x11:
01056 avi->mail_capacity = buf->ReadByte();
01057 break;
01058
01059 case 0x12:
01060 avi->sfx = buf->ReadByte();
01061 break;
01062
01063 case 0x13:
01064 ei->refit_mask = buf->ReadDWord();
01065 _gted[e->index].refitmask_valid = true;
01066 break;
01067
01068 case 0x14:
01069 ei->callback_mask = buf->ReadByte();
01070 break;
01071
01072 case 0x15:
01073 ei->refit_cost = buf->ReadByte();
01074 break;
01075
01076 case 0x16:
01077 ei->retire_early = buf->ReadByte();
01078 break;
01079
01080 case 0x17:
01081 ei->misc_flags = buf->ReadByte();
01082 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
01083 break;
01084
01085 case 0x18:
01086 _gted[e->index].cargo_allowed = buf->ReadWord();
01087 _gted[e->index].refitmask_valid = true;
01088 break;
01089
01090 case 0x19:
01091 _gted[e->index].cargo_disallowed = buf->ReadWord();
01092 _gted[e->index].refitmask_valid = true;
01093 break;
01094
01095 case 0x1A:
01096 ei->base_intro = buf->ReadDWord();
01097 break;
01098
01099 case 0x1B:
01100 AlterVehicleListOrder(e->index, buf->ReadExtended());
01101 break;
01102
01103 default:
01104 ret = CommonVehicleChangeInfo(ei, prop, buf);
01105 break;
01106 }
01107 }
01108
01109 return ret;
01110 }
01111
01112 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
01113 {
01114 ChangeInfoResult ret = CIR_SUCCESS;
01115
01116 if (stid + numinfo > MAX_STATIONS) {
01117 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, MAX_STATIONS);
01118 return CIR_INVALID_ID;
01119 }
01120
01121
01122 if (_cur_grffile->stations == NULL) _cur_grffile->stations = CallocT<StationSpec*>(MAX_STATIONS);
01123
01124 for (int i = 0; i < numinfo; i++) {
01125 StationSpec *statspec = _cur_grffile->stations[stid + i];
01126
01127
01128 if (statspec == NULL && prop != 0x08) {
01129 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
01130 return CIR_INVALID_ID;
01131 }
01132
01133 switch (prop) {
01134 case 0x08: {
01135 StationSpec **spec = &_cur_grffile->stations[stid + i];
01136
01137
01138 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
01139
01140
01141 uint32 classid = buf->ReadDWord();
01142 (*spec)->sclass = AllocateStationClass(BSWAP32(classid));
01143 } break;
01144
01145 case 0x09:
01146 statspec->tiles = buf->ReadExtended();
01147 statspec->renderdata = CallocT<DrawTileSprites>(statspec->tiles);
01148 statspec->copied_renderdata = false;
01149
01150 for (uint t = 0; t < statspec->tiles; t++) {
01151 DrawTileSprites *dts = &statspec->renderdata[t];
01152 uint seq_count = 0;
01153
01154 dts->seq = NULL;
01155 dts->ground.sprite = buf->ReadWord();
01156 dts->ground.pal = buf->ReadWord();
01157 if (dts->ground.sprite == 0) continue;
01158 if (HasBit(dts->ground.pal, 15)) {
01159
01160 ClrBit(dts->ground.pal, 15);
01161 SetBit(dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
01162 }
01163
01164 MapSpriteMappingRecolour(&dts->ground);
01165
01166 while (buf->HasData()) {
01167
01168 dts->seq = ReallocT(const_cast<DrawTileSeqStruct *>(dts->seq), ++seq_count);
01169 DrawTileSeqStruct *dtss = const_cast<DrawTileSeqStruct *>(&dts->seq[seq_count - 1]);
01170
01171 dtss->delta_x = buf->ReadByte();
01172 if ((byte) dtss->delta_x == 0x80) break;
01173 dtss->delta_y = buf->ReadByte();
01174 dtss->delta_z = buf->ReadByte();
01175 dtss->size_x = buf->ReadByte();
01176 dtss->size_y = buf->ReadByte();
01177 dtss->size_z = buf->ReadByte();
01178 dtss->image.sprite = buf->ReadWord();
01179 dtss->image.pal = buf->ReadWord();
01180
01181 if (HasBit(dtss->image.pal, 15)) {
01182 ClrBit(dtss->image.pal, 15);
01183 } else {
01184
01185 SetBit(dtss->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
01186 }
01187
01188 MapSpriteMappingRecolour(&dtss->image);
01189 }
01190 }
01191 break;
01192
01193 case 0x0A: {
01194 byte srcid = buf->ReadByte();
01195 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01196
01197 if (srcstatspec == NULL) {
01198 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
01199 continue;
01200 }
01201
01202 statspec->tiles = srcstatspec->tiles;
01203 statspec->renderdata = srcstatspec->renderdata;
01204 statspec->copied_renderdata = true;
01205 } break;
01206
01207 case 0x0B:
01208 statspec->callback_mask = buf->ReadByte();
01209 break;
01210
01211 case 0x0C:
01212 statspec->disallowed_platforms = buf->ReadByte();
01213 break;
01214
01215 case 0x0D:
01216 statspec->disallowed_lengths = buf->ReadByte();
01217 break;
01218
01219 case 0x0E:
01220 statspec->copied_layouts = false;
01221
01222 while (buf->HasData()) {
01223 byte length = buf->ReadByte();
01224 byte number = buf->ReadByte();
01225 StationLayout layout;
01226 uint l, p;
01227
01228 if (length == 0 || number == 0) break;
01229
01230 if (length > statspec->lengths) {
01231 statspec->platforms = ReallocT(statspec->platforms, length);
01232 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
01233
01234 statspec->layouts = ReallocT(statspec->layouts, length);
01235 memset(statspec->layouts + statspec->lengths, 0,
01236 (length - statspec->lengths) * sizeof(*statspec->layouts));
01237
01238 statspec->lengths = length;
01239 }
01240 l = length - 1;
01241
01242 if (number > statspec->platforms[l]) {
01243 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
01244
01245 memset(statspec->layouts[l] + statspec->platforms[l], 0,
01246 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
01247
01248 statspec->platforms[l] = number;
01249 }
01250
01251 p = 0;
01252 layout = MallocT<byte>(length * number);
01253 try {
01254 for (l = 0; l < length; l++) {
01255 for (p = 0; p < number; p++) {
01256 layout[l * number + p] = buf->ReadByte();
01257 }
01258 }
01259 } catch (...) {
01260 free(layout);
01261 throw;
01262 }
01263
01264 l--;
01265 p--;
01266 free(statspec->layouts[l][p]);
01267 statspec->layouts[l][p] = layout;
01268 }
01269 break;
01270
01271 case 0x0F: {
01272 byte srcid = buf->ReadByte();
01273 const StationSpec *srcstatspec = _cur_grffile->stations[srcid];
01274
01275 if (srcstatspec == NULL) {
01276 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
01277 continue;
01278 }
01279
01280 statspec->lengths = srcstatspec->lengths;
01281 statspec->platforms = srcstatspec->platforms;
01282 statspec->layouts = srcstatspec->layouts;
01283 statspec->copied_layouts = true;
01284 } break;
01285
01286 case 0x10:
01287 statspec->cargo_threshold = buf->ReadWord();
01288 break;
01289
01290 case 0x11:
01291 statspec->pylons = buf->ReadByte();
01292 break;
01293
01294 case 0x12:
01295 statspec->cargo_triggers = buf->ReadDWord();
01296 break;
01297
01298 case 0x13:
01299 statspec->flags = buf->ReadByte();
01300 break;
01301
01302 case 0x14:
01303 statspec->wires = buf->ReadByte();
01304 break;
01305
01306 case 0x15:
01307 statspec->blocked = buf->ReadByte();
01308 break;
01309
01310 case 0x16:
01311 statspec->anim_frames = buf->ReadByte();
01312 statspec->anim_status = buf->ReadByte();
01313 break;
01314
01315 case 0x17:
01316 statspec->anim_speed = buf->ReadByte();
01317 break;
01318
01319 case 0x18:
01320 statspec->anim_triggers = buf->ReadWord();
01321 break;
01322
01323 default:
01324 ret = CIR_UNKNOWN;
01325 break;
01326 }
01327 }
01328
01329 return ret;
01330 }
01331
01332 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
01333 {
01334 ChangeInfoResult ret = CIR_SUCCESS;
01335
01336 if (id + numinfo > CF_END) {
01337 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoreing", id + numinfo, CF_END);
01338 return CIR_INVALID_ID;
01339 }
01340
01341 for (int i = 0; i < numinfo; i++) {
01342 WaterFeature *wf = &_water_feature[id + i];
01343
01344 switch (prop) {
01345 case 0x08:
01346 wf->callback_mask = buf->ReadByte();
01347 break;
01348
01349 case 0x09:
01350 wf->flags = buf->ReadByte();
01351 break;
01352
01353 default:
01354 ret = CIR_UNKNOWN;
01355 break;
01356 }
01357 }
01358
01359 return ret;
01360 }
01361
01362 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
01363 {
01364 ChangeInfoResult ret = CIR_SUCCESS;
01365
01366 if (brid + numinfo > MAX_BRIDGES) {
01367 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
01368 return CIR_INVALID_ID;
01369 }
01370
01371 for (int i = 0; i < numinfo; i++) {
01372 BridgeSpec *bridge = &_bridge[brid + i];
01373
01374 switch (prop) {
01375 case 0x08: {
01376
01377 byte year = buf->ReadByte();
01378 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
01379 break;
01380 }
01381
01382 case 0x09:
01383 bridge->min_length = buf->ReadByte();
01384 break;
01385
01386 case 0x0A:
01387 bridge->max_length = buf->ReadByte();
01388 break;
01389
01390 case 0x0B:
01391 bridge->price = buf->ReadByte();
01392 break;
01393
01394 case 0x0C:
01395 bridge->speed = buf->ReadWord();
01396 break;
01397
01398 case 0x0D: {
01399 byte tableid = buf->ReadByte();
01400 byte numtables = buf->ReadByte();
01401
01402 if (bridge->sprite_table == NULL) {
01403
01404 bridge->sprite_table = CallocT<PalSpriteID*>(7);
01405 }
01406
01407 for (; numtables-- != 0; tableid++) {
01408 if (tableid >= 7) {
01409 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
01410 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
01411 continue;
01412 }
01413
01414 if (bridge->sprite_table[tableid] == NULL) {
01415 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
01416 }
01417
01418 for (byte sprite = 0; sprite < 32; sprite++) {
01419 SpriteID image = buf->ReadWord();
01420 PaletteID pal = buf->ReadWord();
01421
01422 bridge->sprite_table[tableid][sprite].sprite = image;
01423 bridge->sprite_table[tableid][sprite].pal = pal;
01424
01425 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
01426 }
01427 }
01428 } break;
01429
01430 case 0x0E:
01431 bridge->flags = buf->ReadByte();
01432 break;
01433
01434 case 0x0F:
01435 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
01436 break;
01437
01438 case 0x10: {
01439 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01440 if (newone != STR_UNDEFINED) bridge->material = newone;
01441 } break;
01442
01443 case 0x11:
01444 case 0x12: {
01445 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01446 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
01447 } break;
01448
01449 case 0x13:
01450 bridge->price = buf->ReadWord();
01451 break;
01452
01453 default:
01454 ret = CIR_UNKNOWN;
01455 break;
01456 }
01457 }
01458
01459 return ret;
01460 }
01461
01462 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
01463 {
01464 ChangeInfoResult ret = CIR_SUCCESS;
01465
01466 if (hid + numinfo > HOUSE_MAX) {
01467 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, HOUSE_MAX);
01468 return CIR_INVALID_ID;
01469 }
01470
01471
01472 if (_cur_grffile->housespec == NULL) {
01473 _cur_grffile->housespec = CallocT<HouseSpec*>(HOUSE_MAX);
01474 }
01475
01476 for (int i = 0; i < numinfo; i++) {
01477 HouseSpec *housespec = _cur_grffile->housespec[hid + i];
01478
01479 if (prop != 0x08 && housespec == NULL) {
01480 grfmsg(2, "TownHouseChangeInfo: Attempt to modify undefined house %u. Ignoring.", hid + i);
01481 return CIR_INVALID_ID;
01482 }
01483
01484 switch (prop) {
01485 case 0x08: {
01486 HouseSpec **house = &_cur_grffile->housespec[hid + i];
01487 byte subs_id = buf->ReadByte();
01488
01489 if (subs_id == 0xFF) {
01490
01491
01492 HouseSpec::Get(hid + i)->enabled = false;
01493 continue;
01494 } else if (subs_id >= NEW_HOUSE_OFFSET) {
01495
01496 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
01497 continue;
01498 }
01499
01500
01501 if (*house == NULL) *house = CallocT<HouseSpec>(1);
01502
01503 housespec = *house;
01504
01505 MemCpyT(housespec, HouseSpec::Get(subs_id));
01506
01507 housespec->enabled = true;
01508 housespec->local_id = hid + i;
01509 housespec->substitute_id = subs_id;
01510 housespec->grffile = _cur_grffile;
01511 housespec->random_colour[0] = 0x04;
01512 housespec->random_colour[1] = 0x08;
01513 housespec->random_colour[2] = 0x0C;
01514 housespec->random_colour[3] = 0x06;
01515
01516
01517
01518
01519
01520 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
01521 housespec->cargo_acceptance[2] = 0;
01522 }
01523
01529 if (housespec->min_year < 1930) housespec->min_year = 1930;
01530
01531 _loaded_newgrf_features.has_newhouses = true;
01532 } break;
01533
01534 case 0x09:
01535 housespec->building_flags = (BuildingFlags)buf->ReadByte();
01536 break;
01537
01538 case 0x0A: {
01539 uint16 years = buf->ReadWord();
01540 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
01541 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
01542 } break;
01543
01544 case 0x0B:
01545 housespec->population = buf->ReadByte();
01546 break;
01547
01548 case 0x0C:
01549 housespec->mail_generation = buf->ReadByte();
01550 break;
01551
01552 case 0x0D:
01553 case 0x0E:
01554 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
01555 break;
01556
01557 case 0x0F: {
01558 int8 goods = buf->ReadByte();
01559
01560
01561
01562 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
01563 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
01564
01565
01566 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
01567
01568 housespec->accepts_cargo[2] = cid;
01569 housespec->cargo_acceptance[2] = abs(goods);
01570 } break;
01571
01572 case 0x10:
01573 housespec->remove_rating_decrease = buf->ReadWord();
01574 break;
01575
01576 case 0x11:
01577 housespec->removal_cost = buf->ReadByte();
01578 break;
01579
01580 case 0x12:
01581 housespec->building_name = buf->ReadWord();
01582 _string_to_grf_mapping[&housespec->building_name] = _cur_grffile->grfid;
01583 break;
01584
01585 case 0x13:
01586 housespec->building_availability = (HouseZones)buf->ReadWord();
01587 break;
01588
01589 case 0x14:
01590 housespec->callback_mask |= buf->ReadByte();
01591 break;
01592
01593 case 0x15: {
01594 byte override = buf->ReadByte();
01595
01596
01597 if (override >= NEW_HOUSE_OFFSET) {
01598 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
01599 continue;
01600 }
01601
01602 _house_mngr.Add(hid + i, _cur_grffile->grfid, override);
01603 } break;
01604
01605 case 0x16:
01606 housespec->processing_time = buf->ReadByte();
01607 break;
01608
01609 case 0x17:
01610 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
01611 break;
01612
01613 case 0x18:
01614 housespec->probability = buf->ReadByte();
01615 break;
01616
01617 case 0x19:
01618 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
01619 break;
01620
01621 case 0x1A:
01622 housespec->animation_frames = buf->ReadByte();
01623 break;
01624
01625 case 0x1B:
01626 housespec->animation_speed = Clamp(buf->ReadByte(), 2, 16);
01627 break;
01628
01629 case 0x1C:
01630 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur_grffile->grfid);
01631 break;
01632
01633 case 0x1D:
01634 housespec->callback_mask |= (buf->ReadByte() << 8);
01635 break;
01636
01637 case 0x1E: {
01638 uint32 cargotypes = buf->ReadDWord();
01639
01640
01641 if (cargotypes == 0xFFFFFFFF) break;
01642
01643 for (uint j = 0; j < 3; j++) {
01644
01645 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
01646 CargoID cargo = GetCargoTranslation(cargo_part, _cur_grffile);
01647
01648 if (cargo == CT_INVALID) {
01649
01650 housespec->cargo_acceptance[j] = 0;
01651 } else {
01652 housespec->accepts_cargo[j] = cargo;
01653 }
01654 }
01655 } break;
01656
01657 case 0x1F:
01658 housespec->minimum_life = buf->ReadByte();
01659 break;
01660
01661 case 0x20: {
01662 byte count = buf->ReadByte();
01663 for (byte j = 0; j < count; j++) buf->ReadByte();
01664 ret = CIR_UNHANDLED;
01665 } break;
01666
01667 case 0x21:
01668 housespec->min_year = buf->ReadWord();
01669 break;
01670
01671 case 0x22:
01672 housespec->max_year = buf->ReadWord();
01673 break;
01674
01675 default:
01676 ret = CIR_UNKNOWN;
01677 break;
01678 }
01679 }
01680
01681 return ret;
01682 }
01683
01684 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01685 {
01686 ChangeInfoResult ret = CIR_SUCCESS;
01687
01688 for (int i = 0; i < numinfo; i++) {
01689 switch (prop) {
01690 case 0x08: {
01691 int factor = buf->ReadByte();
01692 uint price = gvid + i;
01693
01694 if (price < PR_END) {
01695 _cur_grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
01696 } else {
01697 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
01698 }
01699 } break;
01700
01701 case 0x09:
01702
01703
01704 buf->Skip(4);
01705 break;
01706
01707 case 0x0A: {
01708 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01709 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01710
01711 if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
01712 _currency_specs[curidx].name = newone;
01713 }
01714 } break;
01715
01716 case 0x0B: {
01717 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01718 uint32 rate = buf->ReadDWord();
01719
01720 if (curidx < NUM_CURRENCY) {
01721
01722
01723
01724 _currency_specs[curidx].rate = rate / 1000;
01725 } else {
01726 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
01727 }
01728 } break;
01729
01730 case 0x0C: {
01731 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01732 uint16 options = buf->ReadWord();
01733
01734 if (curidx < NUM_CURRENCY) {
01735 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
01736 _currency_specs[curidx].separator[1] = '\0';
01737
01738
01739 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
01740 } else {
01741 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
01742 }
01743 } break;
01744
01745 case 0x0D: {
01746 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01747 uint32 tempfix = buf->ReadDWord();
01748
01749 if (curidx < NUM_CURRENCY) {
01750 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
01751 _currency_specs[curidx].prefix[4] = 0;
01752 } else {
01753 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01754 }
01755 } break;
01756
01757 case 0x0E: {
01758 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01759 uint32 tempfix = buf->ReadDWord();
01760
01761 if (curidx < NUM_CURRENCY) {
01762 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
01763 _currency_specs[curidx].suffix[4] = 0;
01764 } else {
01765 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01766 }
01767 } break;
01768
01769 case 0x0F: {
01770 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01771 Year year_euro = buf->ReadWord();
01772
01773 if (curidx < NUM_CURRENCY) {
01774 _currency_specs[curidx].to_euro = year_euro;
01775 } else {
01776 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
01777 }
01778 } break;
01779
01780 case 0x10:
01781 if (numinfo > 1 || IsSnowLineSet()) {
01782 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
01783 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
01784 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
01785 } else {
01786 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
01787
01788 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
01789 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
01790 table[i][j] = buf->ReadByte();
01791 }
01792 }
01793 SetSnowLine(table);
01794 }
01795 break;
01796
01797 case 0x11:
01798
01799
01800 buf->Skip(8);
01801 break;
01802
01803 case 0x12:
01804
01805
01806 buf->Skip(4);
01807 break;
01808
01809 default:
01810 ret = CIR_UNKNOWN;
01811 break;
01812 }
01813 }
01814
01815 return ret;
01816 }
01817
01818 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01819 {
01820 ChangeInfoResult ret = CIR_SUCCESS;
01821
01822 for (int i = 0; i < numinfo; i++) {
01823 switch (prop) {
01824 case 0x08:
01825 buf->ReadByte();
01826 break;
01827
01828 case 0x09: {
01829 if (i == 0) {
01830 if (gvid != 0) {
01831 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
01832 return CIR_INVALID_ID;
01833 }
01834
01835 free(_cur_grffile->cargo_list);
01836 _cur_grffile->cargo_max = numinfo;
01837 _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
01838 }
01839
01840 CargoLabel cl = buf->ReadDWord();
01841 _cur_grffile->cargo_list[i] = BSWAP32(cl);
01842 break;
01843 }
01844
01845 case 0x0A:
01846 case 0x0C:
01847 case 0x0F:
01848 buf->ReadWord();
01849 break;
01850
01851 case 0x0B:
01852 case 0x0D:
01853 case 0x0E:
01854 buf->ReadDWord();
01855 break;
01856
01857 case 0x10:
01858 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
01859 break;
01860
01861 case 0x11: {
01862 uint32 s = buf->ReadDWord();
01863 uint32 t = buf->ReadDWord();
01864 SetNewGRFOverride(s, t);
01865 break;
01866 }
01867
01868 case 0x12: {
01869 if (i == 0) {
01870 if (gvid != 0) {
01871 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
01872 return CIR_INVALID_ID;
01873 }
01874
01875 free(_cur_grffile->railtype_list);
01876 _cur_grffile->railtype_max = numinfo;
01877 _cur_grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
01878 }
01879
01880 RailTypeLabel rtl = buf->ReadDWord();
01881 _cur_grffile->railtype_list[i] = BSWAP32(rtl);
01882 break;
01883 }
01884
01885 default:
01886 ret = CIR_UNKNOWN;
01887 break;
01888 }
01889 }
01890
01891 return ret;
01892 }
01893
01894
01895 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
01896 {
01897 ChangeInfoResult ret = CIR_SUCCESS;
01898
01899 if (cid + numinfo > NUM_CARGO) {
01900 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
01901 return CIR_INVALID_ID;
01902 }
01903
01904 for (int i = 0; i < numinfo; i++) {
01905 CargoSpec *cs = CargoSpec::Get(cid + i);
01906
01907 switch (prop) {
01908 case 0x08:
01909 cs->bitnum = buf->ReadByte();
01910 if (cs->IsValid()) {
01911 cs->grffile = _cur_grffile;
01912 SetBit(_cargo_mask, cid + i);
01913 } else {
01914 ClrBit(_cargo_mask, cid + i);
01915 }
01916 break;
01917
01918 case 0x09:
01919 cs->name = buf->ReadWord();
01920 _string_to_grf_mapping[&cs->name] = _cur_grffile->grfid;
01921 break;
01922
01923 case 0x0A:
01924 cs->name_single = buf->ReadWord();
01925 _string_to_grf_mapping[&cs->name_single] = _cur_grffile->grfid;
01926 break;
01927
01928 case 0x0B:
01929
01930
01931 cs->units_volume = buf->ReadWord();
01932 _string_to_grf_mapping[&cs->units_volume] = _cur_grffile->grfid;
01933 break;
01934
01935 case 0x0C:
01936 cs->quantifier = buf->ReadWord();
01937 _string_to_grf_mapping[&cs->quantifier] = _cur_grffile->grfid;
01938 break;
01939
01940 case 0x0D:
01941 cs->abbrev = buf->ReadWord();
01942 _string_to_grf_mapping[&cs->abbrev] = _cur_grffile->grfid;
01943 break;
01944
01945 case 0x0E:
01946 cs->sprite = buf->ReadWord();
01947 break;
01948
01949 case 0x0F:
01950 cs->weight = buf->ReadByte();
01951 break;
01952
01953 case 0x10:
01954 cs->transit_days[0] = buf->ReadByte();
01955 break;
01956
01957 case 0x11:
01958 cs->transit_days[1] = buf->ReadByte();
01959 break;
01960
01961 case 0x12:
01962 cs->initial_payment = buf->ReadDWord();
01963 break;
01964
01965 case 0x13:
01966 cs->rating_colour = MapDOSColour(buf->ReadByte());
01967 break;
01968
01969 case 0x14:
01970 cs->legend_colour = MapDOSColour(buf->ReadByte());
01971 break;
01972
01973 case 0x15:
01974 cs->is_freight = (buf->ReadByte() != 0);
01975 break;
01976
01977 case 0x16:
01978 cs->classes = buf->ReadWord();
01979 break;
01980
01981 case 0x17:
01982 cs->label = buf->ReadDWord();
01983 cs->label = BSWAP32(cs->label);
01984 break;
01985
01986 case 0x18: {
01987 uint8 substitute_type = buf->ReadByte();
01988
01989 switch (substitute_type) {
01990 case 0x00: cs->town_effect = TE_PASSENGERS; break;
01991 case 0x02: cs->town_effect = TE_MAIL; break;
01992 case 0x05: cs->town_effect = TE_GOODS; break;
01993 case 0x09: cs->town_effect = TE_WATER; break;
01994 case 0x0B: cs->town_effect = TE_FOOD; break;
01995 default:
01996 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
01997 case 0xFF: cs->town_effect = TE_NONE; break;
01998 }
01999 } break;
02000
02001 case 0x19:
02002 cs->multipliertowngrowth = buf->ReadWord();
02003 break;
02004
02005 case 0x1A:
02006 cs->callback_mask = buf->ReadByte();
02007 break;
02008
02009 default:
02010 ret = CIR_UNKNOWN;
02011 break;
02012 }
02013 }
02014
02015 return ret;
02016 }
02017
02018
02019 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02020 {
02021 ChangeInfoResult ret = CIR_SUCCESS;
02022
02023 if (_cur_grffile->sound_offset == 0) {
02024 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02025 return CIR_INVALID_ID;
02026 }
02027
02028 for (int i = 0; i < numinfo; i++) {
02029 SoundID sound = sid + i + _cur_grffile->sound_offset - ORIGINAL_SAMPLE_COUNT;
02030
02031 if (sound >= GetNumSounds()) {
02032 grfmsg(1, "SoundEffectChangeInfo: Sound %d not defined (max %d)", sound, GetNumSounds());
02033 return CIR_INVALID_ID;
02034 }
02035
02036 switch (prop) {
02037 case 0x08:
02038 GetSound(sound)->volume = buf->ReadByte();
02039 break;
02040
02041 case 0x09:
02042 GetSound(sound)->priority = buf->ReadByte();
02043 break;
02044
02045 case 0x0A: {
02046 SoundID orig_sound = buf->ReadByte();
02047
02048 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02049 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02050 } else {
02051 SoundEntry *new_sound = GetSound(sound);
02052 SoundEntry *old_sound = GetSound(orig_sound);
02053
02054
02055 *old_sound = *new_sound;
02056 }
02057 } break;
02058
02059 default:
02060 ret = CIR_UNKNOWN;
02061 break;
02062 }
02063 }
02064
02065 return ret;
02066 }
02067
02068 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02069 {
02070 ChangeInfoResult ret = CIR_SUCCESS;
02071
02072 if (indtid + numinfo > NUM_INDUSTRYTILES) {
02073 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02074 return CIR_INVALID_ID;
02075 }
02076
02077
02078 if (_cur_grffile->indtspec == NULL) {
02079 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02080 }
02081
02082 for (int i = 0; i < numinfo; i++) {
02083 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
02084
02085 if (prop != 0x08 && tsp == NULL) {
02086 grfmsg(2, "IndustryTilesChangeInfo: Attempt to modify undefined industry tile %u. Ignoring.", indtid + i);
02087 return CIR_INVALID_ID;
02088 }
02089
02090 switch (prop) {
02091 case 0x08: {
02092 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i];
02093 byte subs_id = buf->ReadByte();
02094
02095 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
02096
02097 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
02098 continue;
02099 }
02100
02101
02102 if (*tilespec == NULL) {
02103 int tempid;
02104 *tilespec = CallocT<IndustryTileSpec>(1);
02105 tsp = *tilespec;
02106
02107 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
02108 tsp->enabled = true;
02109
02110
02111
02112
02113 tsp->anim_production = INDUSTRYTILE_NOANIM;
02114 tsp->anim_next = INDUSTRYTILE_NOANIM;
02115
02116 tsp->grf_prop.local_id = indtid + i;
02117 tsp->grf_prop.subst_id = subs_id;
02118 tsp->grf_prop.grffile = _cur_grffile;
02119 tempid = _industile_mngr.AddEntityID(indtid + i, _cur_grffile->grfid, subs_id);
02120 }
02121 } break;
02122
02123 case 0x09: {
02124 byte ovrid = buf->ReadByte();
02125
02126
02127 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
02128 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
02129 continue;
02130 }
02131
02132 _industile_mngr.Add(indtid + i, _cur_grffile->grfid, ovrid);
02133 } break;
02134
02135 case 0x0A:
02136 case 0x0B:
02137 case 0x0C: {
02138 uint16 acctp = buf->ReadWord();
02139 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
02140 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
02141 } break;
02142
02143 case 0x0D:
02144 tsp->slopes_refused = (Slope)buf->ReadByte();
02145 break;
02146
02147 case 0x0E:
02148 tsp->callback_mask = buf->ReadByte();
02149 break;
02150
02151 case 0x0F:
02152 tsp->animation_info = buf->ReadWord();
02153 break;
02154
02155 case 0x10:
02156 tsp->animation_speed = buf->ReadByte();
02157 break;
02158
02159 case 0x11:
02160 tsp->animation_triggers = buf->ReadByte();
02161 break;
02162
02163 case 0x12:
02164 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
02165 break;
02166
02167 default:
02168 ret = CIR_UNKNOWN;
02169 break;
02170 }
02171 }
02172
02173 return ret;
02174 }
02175
02182 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
02183 {
02184 for (int i = 0; i < size - 1; i++) {
02185 for (int j = i + 1; j < size; j++) {
02186 if (layout[i].ti.x == layout[j].ti.x &&
02187 layout[i].ti.y == layout[j].ti.y) {
02188 return false;
02189 }
02190 }
02191 }
02192 return true;
02193 }
02194
02195 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
02196 {
02197 ChangeInfoResult ret = CIR_SUCCESS;
02198
02199 if (indid + numinfo > NUM_INDUSTRYTYPES) {
02200 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
02201 return CIR_INVALID_ID;
02202 }
02203
02204 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
02205
02206
02207 if (_cur_grffile->industryspec == NULL) {
02208 _cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
02209 }
02210
02211 for (int i = 0; i < numinfo; i++) {
02212 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
02213
02214 if (prop != 0x08 && indsp == NULL) {
02215 grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i);
02216 return CIR_INVALID_ID;
02217 }
02218
02219 switch (prop) {
02220 case 0x08: {
02221 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
02222 byte subs_id = buf->ReadByte();
02223
02224 if (subs_id == 0xFF) {
02225
02226
02227 _industry_specs[indid + i].enabled = false;
02228 continue;
02229 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
02230
02231 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
02232 continue;
02233 }
02234
02235
02236
02237
02238 if (*indspec == NULL) {
02239 *indspec = CallocT<IndustrySpec>(1);
02240 indsp = *indspec;
02241
02242 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
02243 indsp->enabled = true;
02244 indsp->grf_prop.local_id = indid + i;
02245 indsp->grf_prop.subst_id = subs_id;
02246 indsp->grf_prop.grffile = _cur_grffile;
02247
02248
02249 indsp->check_proc = CHECK_NOTHING;
02250 }
02251 } break;
02252
02253 case 0x09: {
02254 byte ovrid = buf->ReadByte();
02255
02256
02257 if (ovrid >= NEW_INDUSTRYOFFSET) {
02258 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
02259 continue;
02260 }
02261 indsp->grf_prop.override = ovrid;
02262 _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
02263 } break;
02264
02265 case 0x0A: {
02266 indsp->num_table = buf->ReadByte();
02267
02268
02269
02270
02271
02272 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
02273 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(indsp->num_table);
02274 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles);
02275 uint size;
02276 const IndustryTileTable *copy_from;
02277
02278 try {
02279 for (byte j = 0; j < indsp->num_table; j++) {
02280 for (uint k = 0;; k++) {
02281 if (k >= def_num_tiles) {
02282 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
02283
02284 def_num_tiles *= 2;
02285 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
02286 }
02287
02288 itt[k].ti.x = buf->ReadByte();
02289
02290 if (itt[k].ti.x == 0xFE && k == 0) {
02291
02292 IndustryType type = buf->ReadByte();
02293 byte laynbr = buf->ReadByte();
02294
02295 copy_from = _origin_industry_specs[type].table[laynbr];
02296 for (size = 1;; size++) {
02297 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
02298 }
02299 break;
02300 }
02301
02302 itt[k].ti.y = buf->ReadByte();
02303
02304 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
02305
02306
02307 itt[k].ti.x = -0x80;
02308 itt[k].ti.y = 0;
02309 itt[k].gfx = 0;
02310
02311 size = k + 1;
02312 copy_from = itt;
02313 break;
02314 }
02315
02316 itt[k].gfx = buf->ReadByte();
02317
02318 if (itt[k].gfx == 0xFE) {
02319
02320 int local_tile_id = buf->ReadWord();
02321
02322
02323 int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
02324
02325 if (tempid == INVALID_INDUSTRYTILE) {
02326 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
02327 } else {
02328
02329 itt[k].gfx = tempid;
02330 size = k + 1;
02331 copy_from = itt;
02332 }
02333 } else if (itt[k].gfx == 0xFF) {
02334 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
02335 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
02336 }
02337 }
02338
02339 if (!ValidateIndustryLayout(copy_from, size)) {
02340
02341 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
02342 indsp->num_table--;
02343 j--;
02344 } else {
02345 tile_table[j] = CallocT<IndustryTileTable>(size);
02346 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
02347 }
02348 }
02349 } catch (...) {
02350 for (int i = 0; i < indsp->num_table; i++) {
02351 free(tile_table[i]);
02352 }
02353 free(tile_table);
02354 free(itt);
02355 throw;
02356 }
02357
02358
02359 indsp->table = tile_table;
02360 SetBit(indsp->cleanup_flag, 1);
02361 free(itt);
02362 } break;
02363
02364 case 0x0B:
02365 indsp->life_type = (IndustryLifeType)buf->ReadByte();
02366 break;
02367
02368 case 0x0C:
02369 indsp->closure_text = buf->ReadWord();
02370 _string_to_grf_mapping[&indsp->closure_text] = _cur_grffile->grfid;
02371 break;
02372
02373 case 0x0D:
02374 indsp->production_up_text = buf->ReadWord();
02375 _string_to_grf_mapping[&indsp->production_up_text] = _cur_grffile->grfid;
02376 break;
02377
02378 case 0x0E:
02379 indsp->production_down_text = buf->ReadWord();
02380 _string_to_grf_mapping[&indsp->production_down_text] = _cur_grffile->grfid;
02381 break;
02382
02383 case 0x0F:
02384 indsp->cost_multiplier = buf->ReadByte();
02385 break;
02386
02387 case 0x10:
02388 for (byte j = 0; j < 2; j++) {
02389 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02390 }
02391 break;
02392
02393 case 0x11:
02394 for (byte j = 0; j < 3; j++) {
02395 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02396 }
02397 buf->ReadByte();
02398 break;
02399
02400 case 0x12:
02401 case 0x13:
02402 indsp->production_rate[prop - 0x12] = buf->ReadByte();
02403 break;
02404
02405 case 0x14:
02406 indsp->minimal_cargo = buf->ReadByte();
02407 break;
02408
02409 case 0x15: {
02410 indsp->number_of_sounds = buf->ReadByte();
02411 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
02412
02413 try {
02414 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
02415 sounds[j] = buf->ReadByte();
02416 }
02417 } catch (...) {
02418 free(sounds);
02419 throw;
02420 }
02421
02422 indsp->random_sounds = sounds;
02423 SetBit(indsp->cleanup_flag, 0);
02424 } break;
02425
02426 case 0x16:
02427 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
02428 break;
02429
02430 case 0x17:
02431 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
02432 break;
02433
02434 case 0x18:
02435 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
02436 break;
02437
02438 case 0x19:
02439 indsp->map_colour = MapDOSColour(buf->ReadByte());
02440 break;
02441
02442 case 0x1A:
02443 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
02444 break;
02445
02446 case 0x1B:
02447 indsp->new_industry_text = buf->ReadWord();
02448 _string_to_grf_mapping[&indsp->new_industry_text] = _cur_grffile->grfid;
02449 break;
02450
02451 case 0x1C:
02452 case 0x1D:
02453 case 0x1E: {
02454 uint32 multiples = buf->ReadDWord();
02455 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
02456 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
02457 } break;
02458
02459 case 0x1F:
02460 indsp->name = buf->ReadWord();
02461 _string_to_grf_mapping[&indsp->name] = _cur_grffile->grfid;
02462 break;
02463
02464 case 0x20:
02465 indsp->prospecting_chance = buf->ReadDWord();
02466 break;
02467
02468 case 0x21:
02469 case 0x22: {
02470 byte aflag = buf->ReadByte();
02471 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
02472 } break;
02473
02474 case 0x23:
02475 indsp->removal_cost_multiplier = buf->ReadDWord();
02476 break;
02477
02478 case 0x24:
02479 indsp->station_name = buf->ReadWord();
02480 _string_to_grf_mapping[&indsp->station_name] = _cur_grffile->grfid;
02481 break;
02482
02483 default:
02484 ret = CIR_UNKNOWN;
02485 break;
02486 }
02487 }
02488
02489 return ret;
02490 }
02491
02492 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
02493 {
02494 ChangeInfoResult ret = CIR_SUCCESS;
02495
02496 extern RailtypeInfo _railtypes[RAILTYPE_END];
02497
02498 if (id + numinfo > RAILTYPE_END) {
02499 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
02500 return CIR_INVALID_ID;
02501 }
02502
02503 for (int i = 0; i < numinfo; i++) {
02504 RailType rt = _cur_grffile->railtype_map[id + i];
02505 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
02506
02507 RailtypeInfo *rti = &_railtypes[rt];
02508
02509 switch (prop) {
02510 case 0x08:
02511
02512 buf->ReadDWord();
02513 break;
02514
02515 case 0x09:
02516 rti->strings.toolbar_caption = buf->ReadWord();
02517 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur_grffile->grfid;
02518 break;
02519
02520 case 0x0A:
02521 rti->strings.menu_text = buf->ReadWord();
02522 _string_to_grf_mapping[&rti->strings.menu_text] = _cur_grffile->grfid;
02523 break;
02524
02525 case 0x0B:
02526 rti->strings.build_caption = buf->ReadWord();
02527 _string_to_grf_mapping[&rti->strings.build_caption] = _cur_grffile->grfid;
02528 break;
02529
02530 case 0x0C:
02531 rti->strings.replace_text = buf->ReadWord();
02532 _string_to_grf_mapping[&rti->strings.replace_text] = _cur_grffile->grfid;
02533 break;
02534
02535 case 0x0D:
02536 rti->strings.new_loco = buf->ReadWord();
02537 _string_to_grf_mapping[&rti->strings.new_loco] = _cur_grffile->grfid;
02538 break;
02539
02540 case 0x0E:
02541 case 0x0F:
02542 {
02543
02544
02545
02546 int n = buf->ReadByte();
02547 for (int j = 0; j != n; j++) {
02548 RailTypeLabel label = buf->ReadDWord();
02549 RailType rt = GetRailTypeByLabel(BSWAP32(label));
02550 if (rt != INVALID_RAILTYPE) {
02551 if (prop == 0x0E) {
02552 SetBit(rti->compatible_railtypes, rt);
02553 } else {
02554 SetBit(rti->powered_railtypes, rt);
02555 }
02556 }
02557 }
02558 break;
02559 }
02560
02561 case 0x10:
02562 rti->flags = (RailTypeFlags)buf->ReadByte();
02563 break;
02564
02565 case 0x11:
02566 rti->curve_speed = buf->ReadByte();
02567 break;
02568
02569 case 0x12:
02570 rti->total_offset = Clamp(buf->ReadByte(), 0, 2) * 82;
02571 break;
02572
02573 case 0x13:
02574 rti->cost_multiplier = buf->ReadByte();
02575 break;
02576
02577 case 0x14:
02578 rti->max_speed = buf->ReadWord();
02579 break;
02580
02581 case 0x15:
02582 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
02583 break;
02584
02585 default:
02586 ret = CIR_UNKNOWN;
02587 break;
02588 }
02589 }
02590
02591 return ret;
02592 }
02593
02594 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
02595 {
02596 ChangeInfoResult ret = CIR_SUCCESS;
02597
02598 if (id + numinfo > RAILTYPE_END) {
02599 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
02600 return CIR_INVALID_ID;
02601 }
02602
02603 for (int i = 0; i < numinfo; i++) {
02604 switch (prop) {
02605 case 0x08:
02606 {
02607 RailTypeLabel rtl = buf->ReadDWord();
02608 rtl = BSWAP32(rtl);
02609
02610 RailType rt = GetRailTypeByLabel(rtl);
02611 if (rt == INVALID_RAILTYPE) {
02612
02613 rt = AllocateRailType(rtl);
02614 }
02615
02616 _cur_grffile->railtype_map[id + i] = rt;
02617 break;
02618 }
02619
02620 case 0x09:
02621 case 0x0A:
02622 case 0x0B:
02623 case 0x0C:
02624 case 0x0D:
02625 case 0x14:
02626 buf->ReadWord();
02627 break;
02628
02629 case 0x0E:
02630 case 0x0F:
02631 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
02632 break;
02633
02634 case 0x10:
02635 case 0x11:
02636 case 0x12:
02637 case 0x13:
02638 case 0x15:
02639 buf->ReadByte();
02640 break;
02641
02642 default:
02643 ret = CIR_UNKNOWN;
02644 break;
02645 }
02646 }
02647
02648 return ret;
02649 }
02650
02651 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
02652 {
02653 switch (cir) {
02654 default: NOT_REACHED();
02655
02656 case CIR_SUCCESS:
02657 return false;
02658
02659 case CIR_UNHANDLED:
02660 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
02661 return false;
02662
02663 case CIR_UNKNOWN:
02664 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
02665
02666
02667 case CIR_INVALID_ID:
02668
02669 _skip_sprites = -1;
02670 _cur_grfconfig->status = GCS_DISABLED;
02671 _cur_grfconfig->error = CallocT<GRFError>(1);
02672 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
02673 _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY;
02674 return true;
02675 }
02676 }
02677
02678
02679 static void FeatureChangeInfo(ByteReader *buf)
02680 {
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692 static const VCI_Handler handler[] = {
02693 RailVehicleChangeInfo,
02694 RoadVehicleChangeInfo,
02695 ShipVehicleChangeInfo,
02696 AircraftVehicleChangeInfo,
02697 StationChangeInfo,
02698 CanalChangeInfo,
02699 BridgeChangeInfo,
02700 TownHouseChangeInfo,
02701 GlobalVarChangeInfo,
02702 IndustrytilesChangeInfo,
02703 IndustriesChangeInfo,
02704 NULL,
02705 SoundEffectChangeInfo,
02706 NULL,
02707 NULL,
02708 NULL,
02709 RailTypeChangeInfo,
02710 };
02711
02712 uint8 feature = buf->ReadByte();
02713 uint8 numprops = buf->ReadByte();
02714 uint numinfo = buf->ReadByte();
02715 uint engine = buf->ReadExtended();
02716
02717 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
02718 feature, numprops, engine, numinfo);
02719
02720 if (feature >= lengthof(handler) || handler[feature] == NULL) {
02721 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
02722 return;
02723 }
02724
02725
02726 SetBit(_cur_grffile->grf_features, feature);
02727
02728 while (numprops-- && buf->HasData()) {
02729 uint8 prop = buf->ReadByte();
02730
02731 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
02732 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
02733 }
02734 }
02735
02736
02737 static void SafeChangeInfo(ByteReader *buf)
02738 {
02739 uint8 feature = buf->ReadByte();
02740 uint8 numprops = buf->ReadByte();
02741 uint numinfo = buf->ReadByte();
02742 buf->ReadExtended();
02743
02744 if (feature == GSF_BRIDGE && numprops == 1) {
02745 uint8 prop = buf->ReadByte();
02746
02747
02748 if (prop == 0x0D) return;
02749 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
02750 uint8 prop = buf->ReadByte();
02751
02752 if (prop == 0x11) {
02753 bool is_safe = true;
02754 for (uint i = 0; i < numinfo; i++) {
02755 uint32 s = buf->ReadDWord();
02756 buf->ReadDWord();
02757 const GRFConfig *grfconfig = GetGRFConfig(s);
02758 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
02759 is_safe = false;
02760 break;
02761 }
02762 }
02763 if (is_safe) return;
02764 }
02765 }
02766
02767 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
02768
02769
02770 _skip_sprites = -1;
02771 }
02772
02773
02774 static void ReserveChangeInfo(ByteReader *buf)
02775 {
02776 uint8 feature = buf->ReadByte();
02777
02778 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
02779
02780 uint8 numprops = buf->ReadByte();
02781 uint8 numinfo = buf->ReadByte();
02782 uint8 index = buf->ReadExtended();
02783
02784 while (numprops-- && buf->HasData()) {
02785 uint8 prop = buf->ReadByte();
02786 ChangeInfoResult cir = CIR_SUCCESS;
02787
02788 switch (feature) {
02789 default: NOT_REACHED();
02790 case GSF_CARGOS:
02791 cir = CargoChangeInfo(index, numinfo, prop, buf);
02792 break;
02793
02794 case GSF_GLOBALVAR:
02795 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
02796 break;
02797
02798 case GSF_RAILTYPES:
02799 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
02800 break;
02801 }
02802
02803 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
02804 }
02805 }
02806
02807
02808 static void NewSpriteSet(ByteReader *buf)
02809 {
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822 uint8 feature = buf->ReadByte();
02823 uint8 num_sets = buf->ReadByte();
02824 uint16 num_ents = buf->ReadExtended();
02825
02826 _cur_grffile->spriteset_start = _cur_spriteid;
02827 _cur_grffile->spriteset_feature = feature;
02828 _cur_grffile->spriteset_numsets = num_sets;
02829 _cur_grffile->spriteset_numents = num_ents;
02830
02831 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
02832 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
02833 );
02834
02835 for (int i = 0; i < num_sets * num_ents; i++) {
02836 _nfo_line++;
02837 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
02838 }
02839 }
02840
02841
02842 static void SkipAct1(ByteReader *buf)
02843 {
02844 buf->ReadByte();
02845 uint8 num_sets = buf->ReadByte();
02846 uint16 num_ents = buf->ReadExtended();
02847
02848 _skip_sprites = num_sets * num_ents;
02849
02850 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
02851 }
02852
02853
02854
02855 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
02856 {
02857 if (HasBit(groupid, 15)) return new CallbackResultSpriteGroup(groupid);
02858
02859 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
02860 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
02861 return NULL;
02862 }
02863
02864 return _cur_grffile->spritegroups[groupid];
02865 }
02866
02867
02868 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
02869 {
02870 if (HasBit(spriteid, 15)) return new CallbackResultSpriteGroup(spriteid);
02871
02872 if (spriteid >= _cur_grffile->spriteset_numsets) {
02873 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
02874 return NULL;
02875 }
02876
02877
02878
02879
02880 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
02881 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
02882 setid, type,
02883 _cur_grffile->spriteset_start + spriteid * num_sprites,
02884 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
02885 return NULL;
02886 }
02887
02888 if (feature != _cur_grffile->spriteset_feature) {
02889 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
02890 setid, type,
02891 _cur_grffile->spriteset_feature, feature);
02892 return NULL;
02893 }
02894
02895 return new ResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
02896 }
02897
02898
02899 static void NewSpriteGroup(ByteReader *buf)
02900 {
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911 SpriteGroup *act_group = NULL;
02912
02913 uint8 feature = buf->ReadByte();
02914 uint8 setid = buf->ReadByte();
02915 uint8 type = buf->ReadByte();
02916
02917 if (setid >= _cur_grffile->spritegroups_count) {
02918
02919 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
02920
02921 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++) {
02922 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
02923 }
02924 }
02925
02926
02927
02928
02929
02930 switch (type) {
02931
02932 case 0x81:
02933 case 0x82:
02934 case 0x85:
02935 case 0x86:
02936 case 0x89:
02937 case 0x8A:
02938 {
02939 byte varadjust;
02940 byte varsize;
02941
02942 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
02943 act_group = group;
02944 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
02945
02946 switch (GB(type, 2, 2)) {
02947 default: NOT_REACHED();
02948 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
02949 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
02950 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
02951 }
02952
02953
02954
02955 do {
02956 DeterministicSpriteGroupAdjust *adjust;
02957
02958 group->num_adjusts++;
02959 group->adjusts = ReallocT(group->adjusts, group->num_adjusts);
02960
02961 adjust = &group->adjusts[group->num_adjusts - 1];
02962
02963
02964 adjust->operation = group->num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
02965 adjust->variable = buf->ReadByte();
02966 if (adjust->variable == 0x7E) {
02967
02968 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
02969 } else {
02970 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
02971 }
02972
02973 varadjust = buf->ReadByte();
02974 adjust->shift_num = GB(varadjust, 0, 5);
02975 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
02976 adjust->and_mask = buf->ReadVarSize(varsize);
02977
02978 if (adjust->type != DSGA_TYPE_NONE) {
02979 adjust->add_val = buf->ReadVarSize(varsize);
02980 adjust->divmod_val = buf->ReadVarSize(varsize);
02981 } else {
02982 adjust->add_val = 0;
02983 adjust->divmod_val = 0;
02984 }
02985
02986
02987 } while (HasBit(varadjust, 5));
02988
02989 group->num_ranges = buf->ReadByte();
02990 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
02991
02992 for (uint i = 0; i < group->num_ranges; i++) {
02993 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
02994 group->ranges[i].low = buf->ReadVarSize(varsize);
02995 group->ranges[i].high = buf->ReadVarSize(varsize);
02996 }
02997
02998 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
02999 break;
03000 }
03001
03002
03003 case 0x80:
03004 case 0x83:
03005 case 0x84:
03006 {
03007 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
03008 act_group = group;
03009 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03010
03011 if (HasBit(type, 2)) {
03012 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
03013 group->count = buf->ReadByte();
03014 }
03015
03016 uint8 triggers = buf->ReadByte();
03017 group->triggers = GB(triggers, 0, 7);
03018 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
03019 group->lowest_randbit = buf->ReadByte();
03020 group->num_groups = buf->ReadByte();
03021 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
03022
03023 for (uint i = 0; i < group->num_groups; i++) {
03024 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
03025 }
03026
03027 break;
03028 }
03029
03030
03031 default:
03032 {
03033 switch (feature) {
03034 case GSF_TRAIN:
03035 case GSF_ROAD:
03036 case GSF_SHIP:
03037 case GSF_AIRCRAFT:
03038 case GSF_STATION:
03039 case GSF_CANAL:
03040 case GSF_CARGOS:
03041 case GSF_RAILTYPES:
03042 {
03043 byte sprites = _cur_grffile->spriteset_numents;
03044 byte num_loaded = type;
03045 byte num_loading = buf->ReadByte();
03046
03047 if (_cur_grffile->spriteset_start == 0) {
03048 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
03049 return;
03050 }
03051
03052 RealSpriteGroup *group = new RealSpriteGroup();
03053 act_group = group;
03054
03055 group->num_loaded = num_loaded;
03056 group->num_loading = num_loading;
03057 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
03058 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
03059
03060 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
03061 setid, sprites, num_loaded, num_loading);
03062
03063 for (uint i = 0; i < num_loaded; i++) {
03064 uint16 spriteid = buf->ReadWord();
03065 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03066 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
03067 }
03068
03069 for (uint i = 0; i < num_loading; i++) {
03070 uint16 spriteid = buf->ReadWord();
03071 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03072 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
03073 }
03074
03075 break;
03076 }
03077
03078 case GSF_TOWNHOUSE:
03079 case GSF_INDUSTRYTILES: {
03080 byte num_spriteset_ents = _cur_grffile->spriteset_numents;
03081 byte num_spritesets = _cur_grffile->spriteset_numsets;
03082 byte num_building_sprites = max((uint8)1, type);
03083 uint i;
03084
03085 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
03086 act_group = group;
03087
03088 group->num_building_stages = max((uint8)1, num_spriteset_ents);
03089 group->dts = CallocT<DrawTileSprites>(1);
03090
03091
03092 group->dts->ground.sprite = buf->ReadWord();
03093 group->dts->ground.pal = buf->ReadWord();
03094
03095
03096 MapSpriteMappingRecolour(&group->dts->ground);
03097
03098 if (HasBit(group->dts->ground.pal, 15)) {
03099
03100
03101 uint spriteset = GB(group->dts->ground.sprite, 0, 14);
03102 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03103 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03104 group->dts->ground.sprite = SPR_IMG_QUERY;
03105 group->dts->ground.pal = PAL_NONE;
03106 } else {
03107 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03108 SB(group->dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
03109 ClrBit(group->dts->ground.pal, 15);
03110 SetBit(group->dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03111 }
03112 }
03113
03114 group->dts->seq = CallocT<DrawTileSeqStruct>(num_building_sprites + 1);
03115
03116 for (i = 0; i < num_building_sprites; i++) {
03117 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts->seq[i]);
03118
03119 seq->image.sprite = buf->ReadWord();
03120 seq->image.pal = buf->ReadWord();
03121 seq->delta_x = buf->ReadByte();
03122 seq->delta_y = buf->ReadByte();
03123
03124 MapSpriteMappingRecolour(&seq->image);
03125
03126 if (HasBit(seq->image.pal, 15)) {
03127
03128
03129 uint spriteset = GB(seq->image.sprite, 0, 14);
03130 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03131 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03132 seq->image.sprite = SPR_IMG_QUERY;
03133 seq->image.pal = PAL_NONE;
03134 } else {
03135 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03136 SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
03137 ClrBit(seq->image.pal, 15);
03138 SetBit(seq->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03139 }
03140 }
03141
03142 if (type > 0) {
03143 seq->delta_z = buf->ReadByte();
03144 if ((byte)seq->delta_z == 0x80) continue;
03145 }
03146
03147 seq->size_x = buf->ReadByte();
03148 seq->size_y = buf->ReadByte();
03149 seq->size_z = buf->ReadByte();
03150 }
03151
03152
03153 const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].delta_x = (int8)0x80;
03154
03155 break;
03156 }
03157
03158 case GSF_INDUSTRIES: {
03159 if (type > 1) {
03160 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
03161 break;
03162 }
03163
03164 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
03165 act_group = group;
03166 group->version = type;
03167 if (type == 0) {
03168 for (uint i = 0; i < 3; i++) {
03169 group->subtract_input[i] = (int16)buf->ReadWord();
03170 }
03171 for (uint i = 0; i < 2; i++) {
03172 group->add_output[i] = buf->ReadWord();
03173 }
03174 group->again = buf->ReadByte();
03175 } else {
03176 for (uint i = 0; i < 3; i++) {
03177 group->subtract_input[i] = buf->ReadByte();
03178 }
03179 for (uint i = 0; i < 2; i++) {
03180 group->add_output[i] = buf->ReadByte();
03181 }
03182 group->again = buf->ReadByte();
03183 }
03184 break;
03185 }
03186
03187
03188 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
03189 }
03190 }
03191 }
03192
03193 _cur_grffile->spritegroups[setid] = act_group;
03194 }
03195
03196 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
03197 {
03198
03199 if (feature == GSF_STATION && ctype == 0xFE) return CT_DEFAULT_NA;
03200 if (ctype == 0xFF) return CT_PURCHASE;
03201
03202 if (_cur_grffile->cargo_max == 0) {
03203
03204 if (ctype >= 32) {
03205 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
03206 return CT_INVALID;
03207 }
03208
03209 const CargoSpec *cs;
03210 FOR_ALL_CARGOSPECS(cs) {
03211 if (cs->bitnum == ctype) {
03212 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
03213 return cs->Index();
03214 }
03215 }
03216
03217 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
03218 return CT_INVALID;
03219 }
03220
03221
03222 if (ctype >= _cur_grffile->cargo_max) {
03223 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
03224 return CT_INVALID;
03225 }
03226
03227
03228 CargoLabel cl = _cur_grffile->cargo_list[ctype];
03229 if (cl == 0) {
03230 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
03231 return CT_INVALID;
03232 }
03233
03234 ctype = GetCargoIDByLabel(cl);
03235 if (ctype == CT_INVALID) {
03236 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));
03237 return CT_INVALID;
03238 }
03239
03240 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);
03241 return ctype;
03242 }
03243
03244
03245 static bool IsValidGroupID(uint16 groupid, const char *function)
03246 {
03247 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03248 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
03249 return false;
03250 }
03251
03252 return true;
03253 }
03254
03255 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
03256 {
03257 static EngineID *last_engines;
03258 static uint last_engines_count;
03259 bool wagover = false;
03260
03261
03262 if (HasBit(idcount, 7)) {
03263 wagover = true;
03264
03265 idcount = GB(idcount, 0, 7);
03266
03267 if (last_engines_count == 0) {
03268 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
03269 return;
03270 }
03271
03272 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
03273 last_engines_count, idcount);
03274 } else {
03275 if (last_engines_count != idcount) {
03276 last_engines = ReallocT(last_engines, idcount);
03277 last_engines_count = idcount;
03278 }
03279 }
03280
03281 EngineID *engines = AllocaM(EngineID, idcount);
03282 for (uint i = 0; i < idcount; i++) {
03283 engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, buf->ReadExtended())->index;
03284 if (!wagover) last_engines[i] = engines[i];
03285 }
03286
03287 uint8 cidcount = buf->ReadByte();
03288 for (uint c = 0; c < cidcount; c++) {
03289 uint8 ctype = buf->ReadByte();
03290 uint16 groupid = buf->ReadWord();
03291 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
03292
03293 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
03294
03295 ctype = TranslateCargo(feature, ctype);
03296 if (ctype == CT_INVALID) continue;
03297
03298 for (uint i = 0; i < idcount; i++) {
03299 EngineID engine = engines[i];
03300
03301 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
03302
03303 if (wagover) {
03304 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03305 } else {
03306 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
03307 }
03308 }
03309 }
03310
03311 uint16 groupid = buf->ReadWord();
03312 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
03313
03314 grfmsg(8, "-- Default group id 0x%04X", groupid);
03315
03316 for (uint i = 0; i < idcount; i++) {
03317 EngineID engine = engines[i];
03318
03319 if (wagover) {
03320 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03321 } else {
03322 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
03323 SetEngineGRF(engine, _cur_grffile);
03324 }
03325 }
03326 }
03327
03328
03329 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
03330 {
03331 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
03332 for (uint i = 0; i < idcount; i++) {
03333 cfs[i] = (CanalFeature)buf->ReadByte();
03334 }
03335
03336 uint8 cidcount = buf->ReadByte();
03337 buf->Skip(cidcount * 3);
03338
03339 uint16 groupid = buf->ReadWord();
03340 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
03341
03342 for (uint i = 0; i < idcount; i++) {
03343 CanalFeature cf = cfs[i];
03344
03345 if (cf >= CF_END) {
03346 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
03347 continue;
03348 }
03349
03350 _water_feature[cf].grffile = _cur_grffile;
03351 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
03352 }
03353 }
03354
03355
03356 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
03357 {
03358 uint8 *stations = AllocaM(uint8, idcount);
03359 for (uint i = 0; i < idcount; i++) {
03360 stations[i] = buf->ReadByte();
03361 }
03362
03363 uint8 cidcount = buf->ReadByte();
03364 for (uint c = 0; c < cidcount; c++) {
03365 uint8 ctype = buf->ReadByte();
03366 uint16 groupid = buf->ReadWord();
03367 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
03368
03369 ctype = TranslateCargo(GSF_STATION, ctype);
03370 if (ctype == CT_INVALID) continue;
03371
03372 for (uint i = 0; i < idcount; i++) {
03373 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03374
03375 if (statspec == NULL) {
03376 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03377 continue;
03378 }
03379
03380 statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
03381 }
03382 }
03383
03384 uint16 groupid = buf->ReadWord();
03385 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
03386
03387 for (uint i = 0; i < idcount; i++) {
03388 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03389
03390 if (statspec == NULL) {
03391 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03392 continue;
03393 }
03394
03395 statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
03396 statspec->grffile = _cur_grffile;
03397 statspec->localidx = stations[i];
03398 SetCustomStationSpec(statspec);
03399 }
03400 }
03401
03402
03403 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
03404 {
03405 uint8 *houses = AllocaM(uint8, idcount);
03406 for (uint i = 0; i < idcount; i++) {
03407 houses[i] = buf->ReadByte();
03408 }
03409
03410
03411 uint8 cidcount = buf->ReadByte();
03412 buf->Skip(cidcount * 3);
03413
03414 uint16 groupid = buf->ReadWord();
03415 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
03416
03417 if (_cur_grffile->housespec == NULL) {
03418 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
03419 return;
03420 }
03421
03422 for (uint i = 0; i < idcount; i++) {
03423 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
03424
03425 if (hs == NULL) {
03426 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
03427 continue;
03428 }
03429
03430 hs->spritegroup = _cur_grffile->spritegroups[groupid];
03431 }
03432 }
03433
03434 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
03435 {
03436 uint8 *industries = AllocaM(uint8, idcount);
03437 for (uint i = 0; i < idcount; i++) {
03438 industries[i] = buf->ReadByte();
03439 }
03440
03441
03442 uint8 cidcount = buf->ReadByte();
03443 buf->Skip(cidcount * 3);
03444
03445 uint16 groupid = buf->ReadWord();
03446 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
03447
03448 if (_cur_grffile->industryspec == NULL) {
03449 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
03450 return;
03451 }
03452
03453 for (uint i = 0; i < idcount; i++) {
03454 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
03455
03456 if (indsp == NULL) {
03457 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
03458 continue;
03459 }
03460
03461 indsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03462 }
03463 }
03464
03465 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
03466 {
03467 uint8 *indtiles = AllocaM(uint8, idcount);
03468 for (uint i = 0; i < idcount; i++) {
03469 indtiles[i] = buf->ReadByte();
03470 }
03471
03472
03473 uint8 cidcount = buf->ReadByte();
03474 buf->Skip(cidcount * 3);
03475
03476 uint16 groupid = buf->ReadWord();
03477 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
03478
03479 if (_cur_grffile->indtspec == NULL) {
03480 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
03481 return;
03482 }
03483
03484 for (uint i = 0; i < idcount; i++) {
03485 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
03486
03487 if (indtsp == NULL) {
03488 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
03489 continue;
03490 }
03491
03492 indtsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03493 }
03494 }
03495
03496 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
03497 {
03498 CargoID *cargos = AllocaM(CargoID, idcount);
03499 for (uint i = 0; i < idcount; i++) {
03500 cargos[i] = buf->ReadByte();
03501 }
03502
03503
03504 uint8 cidcount = buf->ReadByte();
03505 buf->Skip(cidcount * 3);
03506
03507 uint16 groupid = buf->ReadWord();
03508 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
03509
03510 for (uint i = 0; i < idcount; i++) {
03511 CargoID cid = cargos[i];
03512
03513 if (cid >= NUM_CARGO) {
03514 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
03515 continue;
03516 }
03517
03518 CargoSpec *cs = CargoSpec::Get(cid);
03519 cs->grffile = _cur_grffile;
03520 cs->group = _cur_grffile->spritegroups[groupid];
03521 }
03522 }
03523
03524 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
03525 {
03526 uint8 *railtypes = AllocaM(uint8, idcount);
03527 for (uint i = 0; i < idcount; i++) {
03528 railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
03529 }
03530
03531 uint8 cidcount = buf->ReadByte();
03532 for (uint c = 0; c < cidcount; c++) {
03533 uint8 ctype = buf->ReadByte();
03534 uint16 groupid = buf->ReadWord();
03535 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
03536
03537 if (ctype >= RTSG_END) continue;
03538
03539 extern RailtypeInfo _railtypes[RAILTYPE_END];
03540 for (uint i = 0; i < idcount; i++) {
03541 if (railtypes[i] != INVALID_RAILTYPE) {
03542 RailtypeInfo *rti = &_railtypes[railtypes[i]];
03543
03544 rti->group[ctype] = _cur_grffile->spritegroups[groupid];
03545 }
03546 }
03547 }
03548
03549
03550 buf->ReadWord();
03551 }
03552
03553
03554
03555 static void FeatureMapSpriteGroup(ByteReader *buf)
03556 {
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571 if (_cur_grffile->spritegroups == NULL) {
03572 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
03573 return;
03574 }
03575
03576 uint8 feature = buf->ReadByte();
03577 uint8 idcount = buf->ReadByte();
03578
03579
03580 if (idcount == 0) {
03581
03582 buf->ReadByte();
03583 uint16 groupid = buf->ReadWord();
03584
03585 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
03586
03587 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
03588 return;
03589 }
03590
03591
03592 SetBit(_cur_grffile->grf_features, feature);
03593
03594 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
03595
03596 switch (feature) {
03597 case GSF_TRAIN:
03598 case GSF_ROAD:
03599 case GSF_SHIP:
03600 case GSF_AIRCRAFT:
03601 VehicleMapSpriteGroup(buf, feature, idcount);
03602 return;
03603
03604 case GSF_CANAL:
03605 CanalMapSpriteGroup(buf, idcount);
03606 return;
03607
03608 case GSF_STATION:
03609 StationMapSpriteGroup(buf, idcount);
03610 return;
03611
03612 case GSF_TOWNHOUSE:
03613 TownHouseMapSpriteGroup(buf, idcount);
03614 return;
03615
03616 case GSF_INDUSTRIES:
03617 IndustryMapSpriteGroup(buf, idcount);
03618 return;
03619
03620 case GSF_INDUSTRYTILES:
03621 IndustrytileMapSpriteGroup(buf, idcount);
03622 return;
03623
03624 case GSF_CARGOS:
03625 CargoMapSpriteGroup(buf, idcount);
03626 return;
03627
03628 case GSF_RAILTYPES:
03629 RailTypeMapSpriteGroup(buf, idcount);
03630 break;
03631
03632 default:
03633 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
03634 return;
03635 }
03636 }
03637
03638
03639 static void FeatureNewName(ByteReader *buf)
03640 {
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657 bool new_scheme = _cur_grffile->grf_version >= 7;
03658
03659 uint8 feature = buf->ReadByte();
03660 uint8 lang = buf->ReadByte();
03661 uint8 num = buf->ReadByte();
03662 bool generic = HasBit(lang, 7);
03663 uint16 id;
03664 if (generic) {
03665 id = buf->ReadWord();
03666 } else if (feature <= GSF_AIRCRAFT) {
03667 id = buf->ReadExtended();
03668 } else {
03669 id = buf->ReadByte();
03670 }
03671
03672 ClrBit(lang, 7);
03673
03674 uint16 endid = id + num;
03675
03676 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
03677 id, endid, feature, lang);
03678
03679 for (; id < endid && buf->HasData(); id++) {
03680 const char *name = buf->ReadString();
03681 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
03682
03683 switch (feature) {
03684 case GSF_TRAIN:
03685 case GSF_ROAD:
03686 case GSF_SHIP:
03687 case GSF_AIRCRAFT:
03688 if (!generic) {
03689 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
03690 if (e == NULL) break;
03691 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
03692 e->info.string_id = string;
03693 } else {
03694 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03695 }
03696 break;
03697
03698 case GSF_INDUSTRIES: {
03699 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03700 break;
03701 }
03702
03703 case GSF_TOWNHOUSE:
03704 default:
03705 switch (GB(id, 8, 8)) {
03706 case 0xC4:
03707 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03708 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03709 } else {
03710 StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass;
03711 SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
03712 }
03713 break;
03714
03715 case 0xC5:
03716 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03717 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03718 } else {
03719 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03720 }
03721 break;
03722
03723 case 0xC9:
03724 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
03725 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
03726 } else {
03727 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03728 }
03729 break;
03730
03731 case 0xD0:
03732 case 0xD1:
03733 case 0xD2:
03734 case 0xD3:
03735 case 0xDC:
03736 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03737 break;
03738
03739 default:
03740 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03741 break;
03742 }
03743 break;
03744
03745 #if 0
03746 case GSF_CANAL :
03747 case GSF_BRIDGE :
03748 AddGRFString(_cur_spriteid, id, lang, name);
03749 switch (GB(id, 8, 8)) {
03750 case 0xC9:
03751 default:
03752 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03753 }
03754 break;
03755
03756 default :
03757 grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature);
03758 break;
03759 #endif
03760 }
03761 }
03762 }
03763
03772 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
03773 {
03774
03775 if (offset >= max_sprites) {
03776 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
03777 uint orig_num = num;
03778 num = 0;
03779 return orig_num;
03780 }
03781
03782 if (offset + num > max_sprites) {
03783 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
03784 uint orig_num = num;
03785 num = max(max_sprites - offset, 0);
03786 return orig_num - num;
03787 }
03788
03789 return 0;
03790 }
03791
03792
03793 static void GraphicsNew(ByteReader *buf)
03794 {
03795
03796
03797
03798
03799
03800
03801
03802 enum Action5BlockType {
03803 A5BLOCK_FIXED,
03804 A5BLOCK_ALLOW_OFFSET,
03805 A5BLOCK_INVALID,
03806 };
03807 struct Action5Type {
03808 Action5BlockType block_type;
03809 SpriteID sprite_base;
03810 uint16 min_sprites;
03811 uint16 max_sprites;
03812 const char *name;
03813 };
03814
03815 static const Action5Type action5_types[] = {
03816
03817 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
03818 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
03819 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
03820 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
03821 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
03822 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
03823 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
03824 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
03825 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
03826 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
03827 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
03828 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
03829 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
03830 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
03831 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
03832 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
03833 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
03834 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
03835 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
03836 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
03837 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
03838 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
03839 };
03840
03841 uint8 type = buf->ReadByte();
03842 uint16 num = buf->ReadExtended();
03843 uint16 offset = HasBit(type, 7) ? buf->ReadExtended() : 0;
03844 ClrBit(type, 7);
03845
03846 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
03847
03848
03849 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from openttd(d/w).grf.");
03850 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
03851 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
03852 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
03853 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
03854 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
03855 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
03856 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
03857 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
03858 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
03859 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
03860 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
03861 return;
03862 }
03863
03864
03865 if ((type >= lengthof(action5_types)) || (action5_types[type].block_type == A5BLOCK_INVALID)) {
03866 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
03867 _skip_sprites = num;
03868 return;
03869 }
03870
03871 const Action5Type *action5_type = &action5_types[type];
03872
03873
03874 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
03875 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
03876 offset = 0;
03877 }
03878
03879
03880
03881 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
03882 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);
03883 _skip_sprites = num;
03884 return;
03885 }
03886
03887
03888 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
03889 SpriteID replace = action5_type->sprite_base + offset;
03890
03891
03892 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);
03893
03894 for (; num > 0; num--) {
03895 _nfo_line++;
03896 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
03897 }
03898
03899 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
03900
03901 _skip_sprites = skip_num;
03902 }
03903
03904
03905 static void SkipAct5(ByteReader *buf)
03906 {
03907
03908 buf->ReadByte();
03909
03910
03911 _skip_sprites = buf->ReadExtended();
03912
03913 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
03914 }
03915
03926 bool GetGlobalVariable(byte param, uint32 *value)
03927 {
03928 switch (param) {
03929 case 0x00:
03930 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
03931 return true;
03932
03933 case 0x01:
03934 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
03935 return true;
03936
03937 case 0x02: {
03938 YearMonthDay ymd;
03939 ConvertDateToYMD(_date, &ymd);
03940 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
03941 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
03942 return true;
03943 }
03944
03945 case 0x03:
03946 *value = _settings_game.game_creation.landscape;
03947 return true;
03948
03949 case 0x06:
03950 *value = _settings_game.vehicle.road_side << 4;
03951 return true;
03952
03953 case 0x09:
03954 *value = _date_fract * 885;
03955 return true;
03956
03957 case 0x0A:
03958 *value = _tick_counter;
03959 return true;
03960
03961 case 0x0B: {
03962 uint major = 2;
03963 uint minor = 6;
03964 uint revision = 1;
03965 uint build = 1382;
03966 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
03967 return true;
03968 }
03969
03970 case 0x0D:
03971 *value = _cur_grfconfig->windows_paletted;
03972 return true;
03973
03974 case 0x0E:
03975 *value = _cur_grffile->traininfo_vehicle_pitch;
03976 return true;
03977
03978 case 0x0F:
03979 *value = 0;
03980 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
03981 if (_settings_game.vehicle.disable_elrails) {
03982
03983 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
03984 } else {
03985 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
03986
03987 }
03988 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
03989 return true;
03990
03991 case 0x11:
03992 *value = 0;
03993 return true;
03994
03995 case 0x12:
03996 *value = _game_mode;
03997 return true;
03998
03999
04000
04001
04002
04003
04004
04005 case 0x1A:
04006 *value = UINT_MAX;
04007 return true;
04008
04009 case 0x1B:
04010 *value = GB(_display_opt, 0, 6);
04011 return true;
04012
04013 case 0x1D:
04014 *value = 1;
04015 return true;
04016
04017 case 0x1E:
04018 *value = _misc_grf_features;
04019
04020
04021 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
04022 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
04023 return true;
04024
04025
04026
04027 case 0x20:
04028 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
04029 return true;
04030
04031 case 0x21:
04032 *value = _openttd_newgrf_version;
04033 return true;
04034
04035 case 0x22:
04036 *value = _settings_game.difficulty.diff_level;
04037 return true;
04038
04039 case 0x23:
04040 *value = _date;
04041 return true;
04042
04043 case 0x24:
04044 *value = _cur_year;
04045 return true;
04046
04047 default: return false;
04048 }
04049 }
04050
04051 static uint32 GetParamVal(byte param, uint32 *cond_val)
04052 {
04053
04054 uint32 value;
04055 if (GetGlobalVariable(param - 0x80, &value)) return value;
04056
04057
04058 switch (param) {
04059 case 0x84: {
04060 uint32 res = 0;
04061
04062 if (_cur_stage > GLS_INIT) SetBit(res, 0);
04063 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
04064 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
04065 return res;
04066 }
04067
04068 case 0x85:
04069 if (cond_val == NULL) {
04070
04071 return 0;
04072 } else {
04073 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
04074 *cond_val %= 0x20;
04075 return param_val;
04076 }
04077
04078 case 0x88:
04079 return 0;
04080
04081
04082
04083 default:
04084
04085 if (param < 0x80) return _cur_grffile->GetParam(param);
04086
04087
04088 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
04089 return UINT_MAX;
04090 }
04091 }
04092
04093
04094 static void CfgApply(ByteReader *buf)
04095 {
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108 size_t pos = FioGetPos();
04109 uint16 num = FioReadWord();
04110 uint8 type = FioReadByte();
04111 byte *preload_sprite = NULL;
04112
04113
04114 if (type == 0xFF) {
04115 preload_sprite = MallocT<byte>(num);
04116 FioReadBlock(preload_sprite, num);
04117 }
04118
04119
04120 FioSeekTo(pos, SEEK_SET);
04121
04122 if (type != 0xFF) {
04123 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
04124 free(preload_sprite);
04125 return;
04126 }
04127
04128 GRFLocation location(_cur_grfconfig->grfid, _nfo_line + 1);
04129 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
04130 if (it != _grf_line_to_action6_sprite_override.end()) {
04131 free(preload_sprite);
04132 preload_sprite = _grf_line_to_action6_sprite_override[location];
04133 } else {
04134 _grf_line_to_action6_sprite_override[location] = preload_sprite;
04135 }
04136
04137
04138
04139 for (;;) {
04140 uint i;
04141 uint param_num;
04142 uint param_size;
04143 uint offset;
04144 bool add_value;
04145
04146
04147 param_num = buf->ReadByte();
04148 if (param_num == 0xFF) break;
04149
04150
04151
04152 param_size = buf->ReadByte();
04153
04154
04155
04156 add_value = HasBit(param_size, 7);
04157 param_size = GB(param_size, 0, 7);
04158
04159
04160 offset = buf->ReadExtended();
04161
04162
04163
04164 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
04165 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
04166 break;
04167 }
04168
04169 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
04170
04171 bool carry = false;
04172 for (i = 0; i < param_size && offset + i < num; i++) {
04173 uint32 value = GetParamVal(param_num + i / 4, NULL);
04174
04175
04176 if (i == 0) carry = false;
04177
04178 if (add_value) {
04179 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
04180 preload_sprite[offset + i] = GB(new_value, 0, 8);
04181
04182 carry = new_value >= 256;
04183 } else {
04184 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
04185 }
04186 }
04187 }
04188 }
04189
04199 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
04200 {
04201 if (c->error != NULL) {
04202 free(c->error->custom_message);
04203 free(c->error->data);
04204 free(c->error);
04205 }
04206 c->status = GCS_DISABLED;
04207 c->error = CallocT<GRFError>(1);
04208 c->error->data = strdup(_cur_grfconfig->name);
04209 c->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04210 c->error->message = STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC;
04211
04212 ClearTemporaryNewGRFData(GetFileByGRFID(c->grfid));
04213 }
04214
04215
04216
04217 static void SkipIf(ByteReader *buf)
04218 {
04219
04220
04221
04222
04223
04224
04225
04226
04227 uint32 cond_val = 0;
04228 uint32 mask = 0;
04229 bool result;
04230
04231 uint8 param = buf->ReadByte();
04232 uint8 paramsize = buf->ReadByte();
04233 uint8 condtype = buf->ReadByte();
04234
04235 if (condtype < 2) {
04236
04237 paramsize = 1;
04238 }
04239
04240 switch (paramsize) {
04241 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
04242 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
04243 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
04244 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
04245 default: break;
04246 }
04247
04248 if (param < 0x80 && _cur_grffile->param_end <= param) {
04249 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
04250 return;
04251 }
04252
04253 uint32 param_val = GetParamVal(param, &cond_val);
04254
04255 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
04256
04257
04258
04259
04260
04261
04262
04263
04264 if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
04265
04266
04267 GRFConfig *c = GetGRFConfig(cond_val, mask);
04268
04269 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
04270 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04271 c = NULL;
04272 }
04273
04274 if (condtype != 10 && c == NULL) {
04275 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
04276 return;
04277 }
04278
04279 switch (condtype) {
04280
04281 case 0x06:
04282 result = c->status == GCS_ACTIVATED;
04283 break;
04284
04285 case 0x07:
04286 result = c->status != GCS_ACTIVATED;
04287 break;
04288
04289 case 0x08:
04290 result = c->status == GCS_INITIALISED;
04291 break;
04292
04293 case 0x09:
04294 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
04295 break;
04296
04297 case 0x0A:
04298
04299 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
04300 break;
04301
04302 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
04303 }
04304 } else {
04305
04306 switch (condtype) {
04307 case 0x00: result = !!(param_val & (1 << cond_val));
04308 break;
04309 case 0x01: result = !(param_val & (1 << cond_val));
04310 break;
04311 case 0x02: result = (param_val & mask) == cond_val;
04312 break;
04313 case 0x03: result = (param_val & mask) != cond_val;
04314 break;
04315 case 0x04: result = (param_val & mask) < cond_val;
04316 break;
04317 case 0x05: result = (param_val & mask) > cond_val;
04318 break;
04319 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
04320 break;
04321 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
04322 break;
04323 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
04324 break;
04325 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
04326 break;
04327
04328 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
04329 }
04330 }
04331
04332 if (!result) {
04333 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
04334 return;
04335 }
04336
04337 uint8 numsprites = buf->ReadByte();
04338
04339
04340
04341
04342
04343 GRFLabel *choice = NULL;
04344 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
04345 if (label->label != numsprites) continue;
04346
04347
04348 if (choice == NULL) choice = label;
04349
04350 if (label->nfo_line > _nfo_line) {
04351 choice = label;
04352 break;
04353 }
04354 }
04355
04356 if (choice != NULL) {
04357 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
04358 FioSeekTo(choice->pos, SEEK_SET);
04359 _nfo_line = choice->nfo_line;
04360 return;
04361 }
04362
04363 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
04364 _skip_sprites = numsprites;
04365 if (_skip_sprites == 0) {
04366
04367
04368
04369 _skip_sprites = -1;
04370
04371
04372 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
04373 _cur_grfconfig->status = GCS_DISABLED;
04374 ClearTemporaryNewGRFData(_cur_grffile);
04375 }
04376 }
04377 }
04378
04379
04380
04381 static void ScanInfo(ByteReader *buf)
04382 {
04383 buf->ReadByte();
04384 uint32 grfid = buf->ReadDWord();
04385
04386 _cur_grfconfig->grfid = grfid;
04387
04388
04389 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
04390
04391 const char *name = buf->ReadString();
04392 _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name);
04393
04394 if (buf->HasData()) {
04395 const char *info = buf->ReadString();
04396 _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info);
04397 }
04398
04399
04400 _skip_sprites = -1;
04401 }
04402
04403
04404 static void GRFInfo(ByteReader *buf)
04405 {
04406
04407
04408
04409
04410
04411
04412
04413 uint8 version = buf->ReadByte();
04414 uint32 grfid = buf->ReadDWord();
04415 const char *name = buf->ReadString();
04416
04417 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
04418 _cur_grfconfig->status = GCS_DISABLED;
04419 _cur_grfconfig->error = CallocT<GRFError>(1);
04420 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04421 _cur_grfconfig->error->message = STR_NEWGRF_ERROR_MULTIPLE_ACTION_8;
04422
04423 _skip_sprites = -1;
04424 return;
04425 }
04426
04427 _cur_grffile->grfid = grfid;
04428 _cur_grffile->grf_version = version;
04429 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
04430
04431
04432 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
04433 }
04434
04435
04436 static void SpriteReplace(ByteReader *buf)
04437 {
04438
04439
04440
04441
04442
04443
04444
04445
04446 uint8 num_sets = buf->ReadByte();
04447
04448 for (uint i = 0; i < num_sets; i++) {
04449 uint8 num_sprites = buf->ReadByte();
04450 uint16 first_sprite = buf->ReadWord();
04451
04452 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
04453 i, num_sprites, first_sprite
04454 );
04455
04456 for (uint j = 0; j < num_sprites; j++) {
04457 int load_index = first_sprite + j;
04458 _nfo_line++;
04459 LoadNextSprite(load_index, _file_index, _nfo_line);
04460
04461
04462
04463 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
04464 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
04465 }
04466 }
04467 }
04468 }
04469
04470
04471 static void SkipActA(ByteReader *buf)
04472 {
04473 uint8 num_sets = buf->ReadByte();
04474
04475 for (uint i = 0; i < num_sets; i++) {
04476
04477 _skip_sprites += buf->ReadByte();
04478
04479 buf->ReadWord();
04480 }
04481
04482 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
04483 }
04484
04485
04486 static void GRFLoadError(ByteReader *buf)
04487 {
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501
04502
04503 static const StringID msgstr[] = {
04504 STR_NEWGRF_ERROR_VERSION_NUMBER,
04505 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
04506 STR_NEWGRF_ERROR_UNSET_SWITCH,
04507 STR_NEWGRF_ERROR_INVALID_PARAMETER,
04508 STR_NEWGRF_ERROR_LOAD_BEFORE,
04509 STR_NEWGRF_ERROR_LOAD_AFTER,
04510 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
04511 };
04512
04513 static const StringID sevstr[] = {
04514 STR_NEWGRF_ERROR_MSG_INFO,
04515 STR_NEWGRF_ERROR_MSG_WARNING,
04516 STR_NEWGRF_ERROR_MSG_ERROR,
04517 STR_NEWGRF_ERROR_MSG_FATAL
04518 };
04519
04520
04521 if (_cur_grfconfig->error != NULL) return;
04522
04523 byte severity = buf->ReadByte();
04524 byte lang = buf->ReadByte();
04525 byte message_id = buf->ReadByte();
04526
04527
04528 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
04529
04530
04531
04532 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
04533 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
04534 return;
04535 }
04536 ClrBit(severity, 7);
04537
04538 if (severity >= lengthof(sevstr)) {
04539 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
04540 severity = 2;
04541 } else if (severity == 3) {
04542
04543
04544 _cur_grfconfig->status = GCS_DISABLED;
04545 ClearTemporaryNewGRFData(_cur_grffile);
04546 _skip_sprites = -1;
04547 }
04548
04549 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
04550 grfmsg(7, "GRFLoadError: Invalid message id.");
04551 return;
04552 }
04553
04554 if (buf->Remaining() <= 1) {
04555 grfmsg(7, "GRFLoadError: No message data supplied.");
04556 return;
04557 }
04558
04559 GRFError *error = CallocT<GRFError>(1);
04560
04561 error->severity = sevstr[severity];
04562
04563 if (message_id == 0xFF) {
04564
04565 if (buf->HasData()) {
04566 const char *message = buf->ReadString();
04567
04568 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, message);
04569 } else {
04570 grfmsg(7, "GRFLoadError: No custom message supplied.");
04571 error->custom_message = strdup("");
04572 }
04573 } else {
04574 error->message = msgstr[message_id];
04575 }
04576
04577 if (buf->HasData()) {
04578 const char *data = buf->ReadString();
04579
04580 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, data);
04581 } else {
04582 grfmsg(7, "GRFLoadError: No message data supplied.");
04583 error->data = strdup("");
04584 }
04585
04586
04587 uint i = 0;
04588 for (; i < 2 && buf->HasData(); i++) {
04589 uint param_number = buf->ReadByte();
04590 error->param_value[i] = _cur_grffile->GetParam(param_number);
04591 }
04592 error->num_params = i;
04593
04594 _cur_grfconfig->error = error;
04595 }
04596
04597
04598 static void GRFComment(ByteReader *buf)
04599 {
04600
04601
04602
04603
04604 if (!buf->HasData()) return;
04605
04606 const char *text = buf->ReadString();
04607 grfmsg(2, "GRFComment: %s", text);
04608 }
04609
04610
04611 static void SafeParamSet(ByteReader *buf)
04612 {
04613 uint8 target = buf->ReadByte();
04614
04615
04616 if (target < 0x80) return;
04617
04618
04619
04620
04621
04622
04623 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04624
04625
04626 _skip_sprites = -1;
04627 }
04628
04629
04630 static uint32 GetPatchVariable(uint8 param)
04631 {
04632 switch (param) {
04633
04634 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
04635
04636
04637 case 0x0E: return _settings_game.vehicle.freight_trains;
04638
04639
04640 case 0x0F: return 0;
04641
04642
04643
04644
04645 case 0x10:
04646 switch (_settings_game.vehicle.plane_speed) {
04647 default:
04648 case 4: return 1;
04649 case 3: return 2;
04650 case 2: return 2;
04651 case 1: return 4;
04652 }
04653
04654
04655
04656 case 0x11: return SPR_2CCMAP_BASE;
04657
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669 case 0x13: {
04670 byte map_bits = 0;
04671 byte log_X = MapLogX() - 6;
04672 byte log_Y = MapLogY() - 6;
04673 byte max_edge = max(log_X, log_Y);
04674
04675 if (log_X == log_Y) {
04676 SetBit(map_bits, 0);
04677 } else {
04678 if (max_edge == log_Y) SetBit(map_bits, 1);
04679 }
04680
04681 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
04682 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
04683 }
04684
04685 default:
04686 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
04687 return 0;
04688 }
04689 }
04690
04691
04692 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
04693 {
04694 uint start = 0;
04695 uint size = 0;
04696
04697 if (op == 6) {
04698
04699 return grm[_cur_grffile->GetParam(target)];
04700 }
04701
04702
04703 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
04704
04705 for (uint i = start; i < num_ids; i++) {
04706 if (grm[i] == 0) {
04707 size++;
04708 } else {
04709 if (op == 2 || op == 3) break;
04710 start = i + 1;
04711 size = 0;
04712 }
04713
04714 if (size == count) break;
04715 }
04716
04717 if (size == count) {
04718
04719 if (op == 0 || op == 3) {
04720 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
04721 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
04722 }
04723 return start;
04724 }
04725
04726
04727 if (op != 4 && op != 5) {
04728
04729 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
04730 _cur_grfconfig->status = GCS_DISABLED;
04731 ClearTemporaryNewGRFData(_cur_grffile);
04732 _skip_sprites = -1;
04733 return UINT_MAX;
04734 }
04735
04736 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
04737 return UINT_MAX;
04738 }
04739
04740
04741
04742 static void ParamSet(ByteReader *buf)
04743 {
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766 uint8 target = buf->ReadByte();
04767 uint8 oper = buf->ReadByte();
04768 uint32 src1 = buf->ReadByte();
04769 uint32 src2 = buf->ReadByte();
04770
04771 uint32 data = 0;
04772 if (buf->Remaining() >= 4) data = buf->ReadDWord();
04773
04774
04775
04776
04777
04778
04779
04780 if (HasBit(oper, 7)) {
04781 if (target < 0x80 && target < _cur_grffile->param_end) {
04782 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
04783 return;
04784 }
04785
04786 oper = GB(oper, 0, 7);
04787 }
04788
04789 if (src2 == 0xFE) {
04790 if (GB(data, 0, 8) == 0xFF) {
04791 if (data == 0x0000FFFF) {
04792
04793 src1 = GetPatchVariable(src1);
04794 } else {
04795
04796 uint8 op = src1;
04797 uint8 feature = GB(data, 8, 8);
04798 uint16 count = GB(data, 16, 16);
04799
04800 if (_cur_stage == GLS_RESERVE) {
04801 if (feature == 0x08) {
04802
04803 if (op == 0) {
04804
04805 if (_cur_spriteid + count >= 16384) {
04806 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
04807 _cur_grfconfig->status = GCS_DISABLED;
04808 ClearTemporaryNewGRFData(_cur_grffile);
04809 _skip_sprites = -1;
04810 return;
04811 }
04812
04813
04814 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
04815 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
04816 _cur_spriteid += count;
04817 }
04818 }
04819
04820 src1 = 0;
04821 } else if (_cur_stage == GLS_ACTIVATION) {
04822 switch (feature) {
04823 case 0x00:
04824 case 0x01:
04825 case 0x02:
04826 case 0x03:
04827 if (!_settings_game.vehicle.dynamic_engines) {
04828 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
04829 if (_skip_sprites == -1) return;
04830 } else {
04831
04832 switch (op) {
04833 case 2:
04834 case 3:
04835 src1 = _cur_grffile->GetParam(target);
04836 break;
04837
04838 default:
04839 src1 = 0;
04840 break;
04841 }
04842 }
04843 break;
04844
04845 case 0x08:
04846 switch (op) {
04847 case 0:
04848
04849 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
04850 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
04851 break;
04852
04853 case 1:
04854 src1 = _cur_spriteid;
04855 break;
04856
04857 default:
04858 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
04859 return;
04860 }
04861 break;
04862
04863 case 0x0B:
04864
04865 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
04866 if (_skip_sprites == -1) return;
04867 break;
04868
04869 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
04870 }
04871 } else {
04872
04873 src1 = 0;
04874 }
04875 }
04876 } else {
04877
04878 const GRFFile *file = GetFileByGRFID(data);
04879 GRFConfig *c = GetGRFConfig(data);
04880 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
04881
04882 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04883 src1 = 0;
04884 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
04885 src1 = 0;
04886 } else {
04887 src1 = file->GetParam(src1);
04888 }
04889 }
04890 } else {
04891
04892
04893
04894
04895
04896 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
04897 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
04898 }
04899
04900
04901
04902
04903
04904
04905
04906 uint32 res;
04907 switch (oper) {
04908 case 0x00:
04909 res = src1;
04910 break;
04911
04912 case 0x01:
04913 res = src1 + src2;
04914 break;
04915
04916 case 0x02:
04917 res = src1 - src2;
04918 break;
04919
04920 case 0x03:
04921 res = src1 * src2;
04922 break;
04923
04924 case 0x04:
04925 res = (int32)src1 * (int32)src2;
04926 break;
04927
04928 case 0x05:
04929 if ((int32)src2 < 0) {
04930 res = src1 >> -(int32)src2;
04931 } else {
04932 res = src1 << src2;
04933 }
04934 break;
04935
04936 case 0x06:
04937 if ((int32)src2 < 0) {
04938 res = (int32)src1 >> -(int32)src2;
04939 } else {
04940 res = (int32)src1 << src2;
04941 }
04942 break;
04943
04944 case 0x07:
04945 res = src1 & src2;
04946 break;
04947
04948 case 0x08:
04949 res = src1 | src2;
04950 break;
04951
04952 case 0x09:
04953 if (src2 == 0) {
04954 res = src1;
04955 } else {
04956 res = src1 / src2;
04957 }
04958 break;
04959
04960 case 0x0A:
04961 if (src2 == 0) {
04962 res = src1;
04963 } else {
04964 res = (int32)src1 / (int32)src2;
04965 }
04966 break;
04967
04968 case 0x0B:
04969 if (src2 == 0) {
04970 res = src1;
04971 } else {
04972 res = src1 % src2;
04973 }
04974 break;
04975
04976 case 0x0C:
04977 if (src2 == 0) {
04978 res = src1;
04979 } else {
04980 res = (int32)src1 % (int32)src2;
04981 }
04982 break;
04983
04984 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
04985 }
04986
04987 switch (target) {
04988 case 0x8E:
04989 _cur_grffile->traininfo_vehicle_pitch = res;
04990 break;
04991
04992 case 0x8F: {
04993 extern RailtypeInfo _railtypes[RAILTYPE_END];
04994 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
04995 if (_settings_game.vehicle.disable_elrails) {
04996 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
04997 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
04998 } else {
04999 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
05000 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
05001 }
05002 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
05003 break;
05004 }
05005
05006
05007 case 0x93:
05008 case 0x94:
05009 case 0x95:
05010 case 0x96:
05011 case 0x97:
05012 case 0x99:
05013 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05014 break;
05015
05016 case 0x9E:
05017 _misc_grf_features = res;
05018
05019
05020 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
05021
05022
05023 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
05024 break;
05025
05026 case 0x9F:
05027 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05028 break;
05029
05030 default:
05031 if (target < 0x80) {
05032 _cur_grffile->param[target] = res;
05033
05034 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
05035 } else {
05036 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
05037 }
05038 break;
05039 }
05040 }
05041
05042
05043 static void SafeGRFInhibit(ByteReader *buf)
05044 {
05045
05046
05047
05048
05049
05050 uint8 num = buf->ReadByte();
05051
05052 for (uint i = 0; i < num; i++) {
05053 uint32 grfid = buf->ReadDWord();
05054
05055
05056 if (grfid != _cur_grfconfig->grfid) {
05057 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05058
05059
05060 _skip_sprites = -1;
05061
05062 return;
05063 }
05064 }
05065 }
05066
05067
05068 static void GRFInhibit(ByteReader *buf)
05069 {
05070
05071
05072
05073
05074
05075 uint8 num = buf->ReadByte();
05076
05077 for (uint i = 0; i < num; i++) {
05078 uint32 grfid = buf->ReadDWord();
05079 GRFConfig *file = GetGRFConfig(grfid);
05080
05081
05082 if (file != NULL && file != _cur_grfconfig) {
05083 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
05084 file->status = GCS_DISABLED;
05085 }
05086 }
05087 }
05088
05089
05090 static void FeatureTownName(ByteReader *buf)
05091 {
05092
05093
05094
05095
05096
05097
05098
05099 uint32 grfid = _cur_grffile->grfid;
05100
05101 GRFTownName *townname = AddGRFTownName(grfid);
05102
05103 byte id = buf->ReadByte();
05104 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
05105
05106 if (HasBit(id, 7)) {
05107
05108 ClrBit(id, 7);
05109 bool new_scheme = _cur_grffile->grf_version >= 7;
05110
05111 byte lang = buf->ReadByte();
05112
05113 byte nb_gen = townname->nb_gen;
05114 do {
05115 ClrBit(lang, 7);
05116
05117 const char *name = buf->ReadString();
05118
05119 char *lang_name = TranslateTTDPatchCodes(grfid, name);
05120 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
05121 free(lang_name);
05122
05123 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
05124
05125 lang = buf->ReadByte();
05126 } while (lang != 0);
05127 townname->id[nb_gen] = id;
05128 townname->nb_gen++;
05129 }
05130
05131 byte nb = buf->ReadByte();
05132 grfmsg(6, "FeatureTownName: %u parts", nb);
05133
05134 townname->nbparts[id] = nb;
05135 townname->partlist[id] = CallocT<NamePartList>(nb);
05136
05137 for (int i = 0; i < nb; i++) {
05138 byte nbtext = buf->ReadByte();
05139 townname->partlist[id][i].bitstart = buf->ReadByte();
05140 townname->partlist[id][i].bitcount = buf->ReadByte();
05141 townname->partlist[id][i].maxprob = 0;
05142 townname->partlist[id][i].partcount = nbtext;
05143 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
05144 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);
05145
05146 for (int j = 0; j < nbtext; j++) {
05147 byte prob = buf->ReadByte();
05148
05149 if (HasBit(prob, 7)) {
05150 byte ref_id = buf->ReadByte();
05151
05152 if (townname->nbparts[ref_id] == 0) {
05153 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
05154 DelGRFTownName(grfid);
05155 _cur_grfconfig->status = GCS_DISABLED;
05156 ClearTemporaryNewGRFData(_cur_grffile);
05157 _skip_sprites = -1;
05158 return;
05159 }
05160
05161 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
05162 townname->partlist[id][i].parts[j].data.id = ref_id;
05163 } else {
05164 const char *text = buf->ReadString();
05165 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, text);
05166 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
05167 }
05168 townname->partlist[id][i].parts[j].prob = prob;
05169 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
05170 }
05171 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
05172 }
05173 }
05174
05175
05176 static void DefineGotoLabel(ByteReader *buf)
05177 {
05178
05179
05180
05181
05182
05183 byte nfo_label = buf->ReadByte();
05184
05185 GRFLabel *label = MallocT<GRFLabel>(1);
05186 label->label = nfo_label;
05187 label->nfo_line = _nfo_line;
05188 label->pos = FioGetPos();
05189 label->next = NULL;
05190
05191
05192 if (_cur_grffile->label == NULL) {
05193 _cur_grffile->label = label;
05194 } else {
05195
05196 GRFLabel *l;
05197 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
05198 l->next = label;
05199 }
05200
05201 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
05202 }
05203
05204
05205 static void GRFSound(ByteReader *buf)
05206 {
05207
05208
05209
05210
05211 uint16 num = buf->ReadWord();
05212
05213 _grf_data_blocks = num;
05214 _grf_data_type = GDT_SOUND;
05215
05216 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
05217 }
05218
05219
05220 static void SkipAct11(ByteReader *buf)
05221 {
05222
05223
05224
05225
05226 _skip_sprites = buf->ReadWord();
05227
05228 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
05229 }
05230
05231 static void ImportGRFSound(ByteReader *buf)
05232 {
05233 const GRFFile *file;
05234 SoundEntry *sound = AllocateSound();
05235 uint32 grfid = buf->ReadDWord();
05236 SoundID sound_id = buf->ReadWord();
05237
05238 file = GetFileByGRFID(grfid);
05239 if (file == NULL || file->sound_offset == 0) {
05240 grfmsg(1, "ImportGRFSound: Source file not available");
05241 return;
05242 }
05243
05244 if (file->sound_offset + sound_id >= GetNumSounds()) {
05245 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
05246 return;
05247 }
05248
05249 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
05250
05251 *sound = *GetSound(file->sound_offset + sound_id);
05252
05253
05254 sound->volume = 128;
05255 sound->priority = 0;
05256 }
05257
05258
05259 static void GRFImportBlock(ByteReader *buf)
05260 {
05261 if (_grf_data_blocks == 0) {
05262 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
05263 return;
05264 }
05265
05266 _grf_data_blocks--;
05267
05268
05269
05270 if (buf->ReadByte() != _grf_data_type) {
05271 grfmsg(1, "GRFImportBlock: Import type mismatch");
05272 }
05273
05274 switch (_grf_data_type) {
05275 case GDT_SOUND: ImportGRFSound(buf); break;
05276 default: NOT_REACHED();
05277 }
05278 }
05279
05280 static void LoadGRFSound(ByteReader *buf)
05281 {
05282
05283
05284 SoundEntry *sound = AllocateSound();
05285
05286 if (buf->ReadDWord() != BSWAP32('RIFF')) {
05287 grfmsg(1, "LoadGRFSound: Missing RIFF header");
05288 return;
05289 }
05290
05291 uint32 total_size = buf->ReadDWord();
05292 if (total_size > buf->Remaining()) {
05293 grfmsg(1, "LoadGRFSound: RIFF was truncated");
05294 return;
05295 }
05296
05297 if (buf->ReadDWord() != BSWAP32('WAVE')) {
05298 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
05299 return;
05300 }
05301
05302 while (total_size >= 8) {
05303 uint32 tag = buf->ReadDWord();
05304 uint32 size = buf->ReadDWord();
05305 total_size -= 8;
05306 if (total_size < size) {
05307 grfmsg(1, "LoadGRFSound: Invalid RIFF");
05308 return;
05309 }
05310 total_size -= size;
05311
05312 switch (tag) {
05313 case ' tmf':
05314
05315 if (size < 16 || buf->ReadWord() != 1) {
05316 grfmsg(1, "LoadGRFSound: Invalid audio format");
05317 return;
05318 }
05319 sound->channels = buf->ReadWord();
05320 sound->rate = buf->ReadDWord();
05321 buf->ReadDWord();
05322 buf->ReadWord();
05323 sound->bits_per_sample = buf->ReadWord();
05324
05325
05326 size -= 16;
05327 break;
05328
05329 case 'atad':
05330 sound->file_size = size;
05331 sound->file_offset = FioGetPos() - buf->Remaining();
05332 sound->file_slot = _file_index;
05333
05334
05335 sound->volume = 0x80;
05336 sound->priority = 0;
05337
05338 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
05339 return;
05340
05341 default:
05342
05343 break;
05344 }
05345
05346
05347 for (; size > 0; size--) buf->ReadByte();
05348 }
05349
05350 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
05351
05352
05353 MemSetT(sound, 0);
05354 }
05355
05356
05357 static void LoadFontGlyph(ByteReader *buf)
05358 {
05359
05360
05361
05362
05363
05364
05365
05366 uint8 num_def = buf->ReadByte();
05367
05368 for (uint i = 0; i < num_def; i++) {
05369 FontSize size = (FontSize)buf->ReadByte();
05370 uint8 num_char = buf->ReadByte();
05371 uint16 base_char = buf->ReadWord();
05372
05373 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
05374
05375 for (uint c = 0; c < num_char; c++) {
05376 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
05377 _nfo_line++;
05378 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
05379 }
05380 }
05381 }
05382
05383
05384 static void SkipAct12(ByteReader *buf)
05385 {
05386
05387
05388
05389
05390
05391
05392
05393 uint8 num_def = buf->ReadByte();
05394
05395 for (uint i = 0; i < num_def; i++) {
05396
05397 buf->ReadByte();
05398
05399
05400 _skip_sprites += buf->ReadByte();
05401
05402
05403 buf->ReadWord();
05404 }
05405
05406 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
05407 }
05408
05409
05410 static void TranslateGRFStrings(ByteReader *buf)
05411 {
05412
05413
05414
05415
05416
05417
05418
05419 uint32 grfid = buf->ReadDWord();
05420 const GRFConfig *c = GetGRFConfig(grfid);
05421 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
05422 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
05423 return;
05424 }
05425
05426 if (c->status == GCS_INITIALISED) {
05427
05428
05429 GRFError *error = CallocT<GRFError>(1);
05430
05431 char tmp[256];
05432 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
05433 error->data = strdup(tmp);
05434
05435 error->message = STR_NEWGRF_ERROR_LOAD_AFTER;
05436 error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
05437
05438 if (_cur_grfconfig->error != NULL) free(_cur_grfconfig->error);
05439 _cur_grfconfig->error = error;
05440
05441 _cur_grfconfig->status = GCS_DISABLED;
05442 ClearTemporaryNewGRFData(_cur_grffile);
05443 _skip_sprites = -1;
05444 return;
05445 }
05446
05447 byte num_strings = buf->ReadByte();
05448 uint16 first_id = buf->ReadWord();
05449
05450 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
05451 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
05452 return;
05453 }
05454
05455 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
05456 const char *string = buf->ReadString();
05457
05458 if (StrEmpty(string)) {
05459 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
05460 continue;
05461 }
05462
05463
05464
05465
05466
05467
05468 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
05469 }
05470 }
05471
05472
05473 static void GRFDataBlock(ByteReader *buf)
05474 {
05475
05476
05477 if (_grf_data_blocks == 0) {
05478 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
05479 return;
05480 }
05481
05482 uint8 name_len = buf->ReadByte();
05483 const char *name = reinterpret_cast<const char *>(buf->Data());
05484 buf->Skip(name_len);
05485
05486
05487 if (buf->ReadByte() != 0) {
05488 grfmsg(2, "GRFDataBlock: Name not properly terminated");
05489 return;
05490 }
05491
05492 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
05493
05494 _grf_data_blocks--;
05495
05496 switch (_grf_data_type) {
05497 case GDT_SOUND: LoadGRFSound(buf); break;
05498 default: NOT_REACHED();
05499 }
05500 }
05501
05502
05503
05504 static void GRFUnsafe(ByteReader *buf)
05505 {
05506 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05507
05508
05509 _skip_sprites = -1;
05510 }
05511
05512
05513 static void InitializeGRFSpecial()
05514 {
05515 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
05516 | (1 << 0x0D)
05517 | (1 << 0x0E)
05518 | ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)
05519 | (0 << 0x10)
05520 | (1 << 0x12)
05521 | (1 << 0x13)
05522 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
05523 | (1 << 0x1B)
05524 | (1 << 0x1D)
05525 | (1 << 0x1E);
05526
05527 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
05528 | ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)
05529 | (1 << 0x09)
05530 | (0 << 0x0B)
05531 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
05532 | (1 << 0x12)
05533 | (1 << 0x13)
05534 | (1 << 0x14)
05535 | (1 << 0x16)
05536 | (1 << 0x17)
05537 | (1 << 0x18)
05538 | (1 << 0x19)
05539 | (1 << 0x1A)
05540 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
05541 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
05542
05543 _ttdpatch_flags[2] = (1 << 0x01)
05544 | (1 << 0x03)
05545 | (0 << 0x0B)
05546 | (0 << 0x0C)
05547 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
05548 | (1 << 0x0E)
05549 | (1 << 0x0F)
05550 | (0 << 0x10)
05551 | (0 << 0x11)
05552 | (1 << 0x12)
05553 | (1 << 0x13)
05554 | (1 << 0x14)
05555 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
05556 | (1 << 0x16)
05557 | (1 << 0x17)
05558 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
05559 | (1 << 0x19)
05560 | (1 << 0x1A)
05561 | (1 << 0x1B)
05562 | (1 << 0x1C)
05563 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
05564 | (1 << 0x1E)
05565 | (0 << 0x1F);
05566
05567 _ttdpatch_flags[3] = (0 << 0x00)
05568 | (1 << 0x01)
05569 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
05570 | (1 << 0x03)
05571 | (0 << 0x04)
05572 | (1 << 0x05)
05573 | (1 << 0x06)
05574 | (1 << 0x07)
05575 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
05576 | (0 << 0x09)
05577 | (0 << 0x0A)
05578 | (1 << 0x0B)
05579 | (1 << 0x0C)
05580 | (1 << 0x0D)
05581 | ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)
05582 | (1 << 0x0F)
05583 | (1 << 0x10)
05584 | (1 << 0x11)
05585 | (1 << 0x12)
05586 | (0 << 0x13)
05587 | (1 << 0x14)
05588 | (0 << 0x15)
05589 | (1 << 0x16)
05590 | (1 << 0x17)
05591 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
05592 | (1 << 0x1E)
05593 | (1 << 0x1F);
05594 }
05595
05596 static void ResetCustomStations()
05597 {
05598 const GRFFile * const *end = _grf_files.End();
05599 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05600 StationSpec **&stations = (*file)->stations;
05601 if (stations == NULL) continue;
05602 for (uint i = 0; i < MAX_STATIONS; i++) {
05603 if (stations[i] == NULL) continue;
05604 StationSpec *statspec = stations[i];
05605
05606
05607 if (!statspec->copied_renderdata) {
05608 for (uint t = 0; t < statspec->tiles; t++) {
05609 free((void*)statspec->renderdata[t].seq);
05610 }
05611 free(statspec->renderdata);
05612 }
05613
05614
05615 if (!statspec->copied_layouts) {
05616 for (uint l = 0; l < statspec->lengths; l++) {
05617 for (uint p = 0; p < statspec->platforms[l]; p++) {
05618 free(statspec->layouts[l][p]);
05619 }
05620 free(statspec->layouts[l]);
05621 }
05622 free(statspec->layouts);
05623 free(statspec->platforms);
05624 }
05625
05626
05627 free(statspec);
05628 }
05629
05630
05631 free(stations);
05632 stations = NULL;
05633 }
05634 }
05635
05636 static void ResetCustomHouses()
05637 {
05638 const GRFFile * const *end = _grf_files.End();
05639 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05640 HouseSpec **&housespec = (*file)->housespec;
05641 if (housespec == NULL) continue;
05642 for (uint i = 0; i < HOUSE_MAX; i++) {
05643 free(housespec[i]);
05644 }
05645
05646 free(housespec);
05647 housespec = NULL;
05648 }
05649 }
05650
05651 static void ResetCustomIndustries()
05652 {
05653 const GRFFile * const *end = _grf_files.End();
05654 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05655 IndustrySpec **&industryspec = (*file)->industryspec;
05656 IndustryTileSpec **&indtspec = (*file)->indtspec;
05657
05658
05659
05660 if (industryspec != NULL) {
05661 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
05662 IndustrySpec *ind = industryspec[i];
05663 if (ind == NULL) continue;
05664
05665
05666 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
05667 free((void*)ind->random_sounds);
05668 }
05669
05670
05671 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
05672 for (int j = 0; j < ind->num_table; j++) {
05673
05674 free((void*)ind->table[j]);
05675 }
05676
05677 free((void*)ind->table);
05678 ind->table = NULL;
05679 }
05680
05681 free(ind);
05682 }
05683
05684 free(industryspec);
05685 industryspec = NULL;
05686 }
05687
05688 if (indtspec == NULL) continue;
05689 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
05690 free(indtspec[i]);
05691 }
05692
05693 free(indtspec);
05694 indtspec = NULL;
05695 }
05696 }
05697
05698 static void ResetNewGRF()
05699 {
05700 const GRFFile * const *end = _grf_files.End();
05701 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05702 GRFFile *f = *file;
05703 free(f->filename);
05704 free(f->cargo_list);
05705 free(f->railtype_list);
05706 free(f);
05707 }
05708
05709 _grf_files.Clear();
05710 _cur_grffile = NULL;
05711 }
05712
05713 static void ResetNewGRFErrors()
05714 {
05715 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
05716 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
05717 free(c->error->custom_message);
05718 free(c->error->data);
05719 free(c->error);
05720 c->error = NULL;
05721 }
05722 }
05723 }
05724
05729 static void ResetNewGRFData()
05730 {
05731 CleanUpStrings();
05732 CleanUpGRFTownNames();
05733
05734
05735 SetupEngines();
05736
05737
05738 ResetBridges();
05739
05740
05741 ResetRailTypes();
05742
05743
05744 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
05745
05746
05747 memset(&_grm_engines, 0, sizeof(_grm_engines));
05748 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
05749
05750
05751 ResetGenericCallbacks();
05752
05753
05754 ResetPriceBaseMultipliers();
05755
05756
05757 ResetCurrencies();
05758
05759
05760 ResetCustomHouses();
05761 ResetHouses();
05762
05763
05764 ResetCustomIndustries();
05765 ResetIndustries();
05766
05767
05768 ResetStationClasses();
05769 ResetCustomStations();
05770
05771
05772 memset(_water_feature, 0, sizeof(_water_feature));
05773
05774
05775 ClearSnowLine();
05776
05777
05778 ResetNewGRF();
05779
05780
05781 ResetNewGRFErrors();
05782
05783
05784 SetupCargoForClimate(_settings_game.game_creation.landscape);
05785
05786
05787 _misc_grf_features = 0;
05788
05789 _loaded_newgrf_features.has_2CC = false;
05790 _loaded_newgrf_features.has_newhouses = false;
05791 _loaded_newgrf_features.has_newindustries = false;
05792 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
05793
05794
05795 _grf_id_overrides.clear();
05796
05797 InitializeSoundPool();
05798 _spritegroup_pool.CleanPool();
05799 }
05800
05801 static void BuildCargoTranslationMap()
05802 {
05803 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
05804
05805 for (CargoID c = 0; c < NUM_CARGO; c++) {
05806 const CargoSpec *cs = CargoSpec::Get(c);
05807 if (!cs->IsValid()) continue;
05808
05809 if (_cur_grffile->cargo_max == 0) {
05810
05811 _cur_grffile->cargo_map[c] = cs->bitnum;
05812 } else {
05813
05814 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
05815 if (cs->label == _cur_grffile->cargo_list[i]) {
05816 _cur_grffile->cargo_map[c] = i;
05817 break;
05818 }
05819 }
05820 }
05821 }
05822 }
05823
05824 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
05825 {
05826 GRFFile *newfile = GetFileByFilename(config->filename);
05827 if (newfile != NULL) {
05828
05829 newfile->sprite_offset = sprite_offset;
05830 _cur_grffile = newfile;
05831 return;
05832 }
05833
05834 newfile = CallocT<GRFFile>(1);
05835
05836 if (newfile == NULL) error ("Out of memory");
05837
05838 newfile->filename = strdup(config->filename);
05839 newfile->sprite_offset = sprite_offset;
05840
05841
05842 newfile->traininfo_vehicle_pitch = 0;
05843 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
05844
05845
05846 for (Price i = PR_BEGIN; i < PR_END; i++) {
05847 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
05848 }
05849
05850
05851 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
05852 newfile->railtype_map[0] = RAILTYPE_RAIL;
05853 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
05854 newfile->railtype_map[2] = RAILTYPE_MONO;
05855 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
05856
05857
05858
05859 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
05860 memset(newfile->param, 0, sizeof(newfile->param));
05861
05862 assert(config->num_params <= lengthof(config->param));
05863 newfile->param_end = config->num_params;
05864 if (newfile->param_end > 0) {
05865 MemCpyT(newfile->param, config->param, newfile->param_end);
05866 }
05867
05868 *_grf_files.Append() = _cur_grffile = newfile;
05869 }
05870
05871
05874 static const CargoLabel _default_refitmasks_rail[] = {
05875 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
05876 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
05877 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05878 'PLST', 'FZDR',
05879 0 };
05880
05881 static const CargoLabel _default_refitmasks_road[] = {
05882 0 };
05883
05884 static const CargoLabel _default_refitmasks_ships[] = {
05885 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
05886 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
05887 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05888 'PLST', 'FZDR',
05889 0 };
05890
05891 static const CargoLabel _default_refitmasks_aircraft[] = {
05892 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
05893 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
05894 0 };
05895
05896 static const CargoLabel * const _default_refitmasks[] = {
05897 _default_refitmasks_rail,
05898 _default_refitmasks_road,
05899 _default_refitmasks_ships,
05900 _default_refitmasks_aircraft,
05901 };
05902
05903
05907 static void CalculateRefitMasks()
05908 {
05909 Engine *e;
05910
05911 FOR_ALL_ENGINES(e) {
05912 EngineID engine = e->index;
05913 EngineInfo *ei = &e->info;
05914 uint32 mask = 0;
05915 uint32 not_mask = 0;
05916 uint32 xor_mask = 0;
05917
05918
05919 if (_gted[engine].refitmask_valid) {
05920 if (ei->refit_mask != 0) {
05921 const GRFFile *file = e->grffile;
05922 if (file != NULL && file->cargo_max != 0) {
05923
05924 uint num_cargo = min(32, file->cargo_max);
05925 for (uint i = 0; i < num_cargo; i++) {
05926 if (!HasBit(ei->refit_mask, i)) continue;
05927
05928 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
05929 if (c == CT_INVALID) continue;
05930
05931 SetBit(xor_mask, c);
05932 }
05933 } else {
05934
05935 const CargoSpec *cs;
05936 FOR_ALL_CARGOSPECS(cs) {
05937 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
05938 }
05939 }
05940 }
05941
05942 if (_gted[engine].cargo_allowed != 0) {
05943
05944 const CargoSpec *cs;
05945 FOR_ALL_CARGOSPECS(cs) {
05946 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
05947 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
05948 }
05949 }
05950 } else {
05951
05952 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
05953 const CargoLabel *cl = _default_refitmasks[e->type];
05954 for (uint i = 0;; i++) {
05955 if (cl[i] == 0) break;
05956
05957 CargoID cargo = GetCargoIDByLabel(cl[i]);
05958 if (cargo == CT_INVALID) continue;
05959
05960 SetBit(xor_mask, cargo);
05961 }
05962 }
05963 }
05964
05965 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
05966
05967
05968
05969 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
05970 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
05971
05972
05973 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
05974 }
05975 }
05976
05981 static void FinaliseHouseArray()
05982 {
05983
05984
05985
05986
05987
05988
05989
05990
05991
05992 Year min_year = MAX_YEAR;
05993
05994 const GRFFile * const *end = _grf_files.End();
05995 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05996 HouseSpec **&housespec = (*file)->housespec;
05997 if (housespec == NULL) continue;
05998
05999 for (int i = 0; i < HOUSE_MAX; i++) {
06000 HouseSpec *hs = housespec[i];
06001
06002 if (hs == NULL) continue;
06003
06004 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
06005 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
06006 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
06007
06008 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
06009 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
06010 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
06011 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
06012 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
06013 hs->enabled = false;
06014 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", (*file)->filename, hs->local_id);
06015 continue;
06016 }
06017
06018
06019
06020
06021 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
06022 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
06023 hs->enabled = false;
06024 DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", (*file)->filename, hs->local_id);
06025 continue;
06026 }
06027
06028 _house_mngr.SetEntitySpec(hs);
06029 if (hs->min_year < min_year) min_year = hs->min_year;
06030 }
06031 }
06032
06033 if (min_year != 0) {
06034 for (int i = 0; i < HOUSE_MAX; i++) {
06035 HouseSpec *hs = HouseSpec::Get(i);
06036
06037 if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
06038 }
06039 }
06040 }
06041
06045 static void FinaliseIndustriesArray()
06046 {
06047 const GRFFile * const *end = _grf_files.End();
06048 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06049 IndustrySpec **&industryspec = (*file)->industryspec;
06050 IndustryTileSpec **&indtspec = (*file)->indtspec;
06051 if (industryspec != NULL) {
06052 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
06053 IndustrySpec *indsp = industryspec[i];
06054
06055 if (indsp != NULL && indsp->enabled) {
06056 StringID strid;
06057
06058
06059
06060 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
06061 if (strid != STR_UNDEFINED) indsp->name = strid;
06062
06063 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
06064 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
06065
06066 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
06067 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
06068
06069 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
06070 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
06071
06072 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
06073 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
06074
06075 if (indsp->station_name != STR_NULL) {
06076
06077
06078 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
06079 if (strid != STR_UNDEFINED) indsp->station_name = strid;
06080 }
06081
06082 _industry_mngr.SetEntitySpec(indsp);
06083 _loaded_newgrf_features.has_newindustries = true;
06084 }
06085 }
06086 }
06087
06088 if (indtspec != NULL) {
06089 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
06090 IndustryTileSpec *indtsp = indtspec[i];
06091 if (indtsp != NULL) {
06092 _industile_mngr.SetEntitySpec(indtsp);
06093 }
06094 }
06095 }
06096 }
06097
06098 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
06099 IndustrySpec *indsp = &_industry_specs[j];
06100 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
06101 for (uint i = 0; i < 3; i++) {
06102 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
06103 }
06104 }
06105 }
06106 }
06107
06108
06109
06110
06111
06112
06113
06114 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
06115 {
06116
06117
06118
06119
06120
06121
06122
06123
06124
06125
06126
06127
06128 static const SpecialSpriteHandler handlers[][GLS_END] = {
06129 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
06130 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
06131 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
06132 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
06133 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
06134 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
06135 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
06136 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
06137 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
06138 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
06139 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
06140 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
06141 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
06142 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
06143 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
06144 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
06145 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
06146 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
06147 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
06148 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
06149 };
06150
06151 GRFLocation location(_cur_grfconfig->grfid, _nfo_line);
06152
06153 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
06154 if (it == _grf_line_to_action6_sprite_override.end()) {
06155
06156
06157 FioReadBlock(buf, num);
06158 } else {
06159
06160 buf = _grf_line_to_action6_sprite_override[location];
06161 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
06162
06163
06164 FioSeekTo(num, SEEK_CUR);
06165 }
06166
06167 ByteReader br(buf, buf + num);
06168 ByteReader *bufp = &br;
06169
06170 try {
06171 byte action = bufp->ReadByte();
06172
06173 if (action == 0xFF) {
06174 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
06175 GRFDataBlock(bufp);
06176 } else if (action == 0xFE) {
06177 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
06178 GRFImportBlock(bufp);
06179 } else if (action >= lengthof(handlers)) {
06180 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
06181 } else if (handlers[action][stage] == NULL) {
06182 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
06183 } else {
06184 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
06185 handlers[action][stage](bufp);
06186 }
06187 } catch (...) {
06188 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
06189
06190 _skip_sprites = -1;
06191 _cur_grfconfig->status = GCS_DISABLED;
06192 _cur_grfconfig->error = CallocT<GRFError>(1);
06193 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06194 _cur_grfconfig->error->message = STR_NEWGRF_ERROR_READ_BOUNDS;
06195 }
06196 }
06197
06198
06199 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
06200 {
06201 const char *filename = config->filename;
06202 uint16 num;
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
06214 _cur_grffile = GetFileByFilename(filename);
06215 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
06216 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
06217 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
06218 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
06219 }
06220
06221 if (file_index > LAST_GRF_SLOT) {
06222 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
06223 config->status = GCS_DISABLED;
06224 config->error = CallocT<GRFError>(1);
06225 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06226 config->error->message = STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED;
06227 return;
06228 }
06229
06230 FioOpenFile(file_index, filename);
06231 _file_index = file_index;
06232 _palette_remap_grf[_file_index] = (config->windows_paletted != (_use_palette == PAL_WINDOWS));
06233
06234 _cur_grfconfig = config;
06235
06236 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
06237
06238
06239
06240
06241 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
06242 FioReadDword();
06243 } else {
06244 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
06245 return;
06246 }
06247
06248 _skip_sprites = 0;
06249 _nfo_line = 0;
06250
06251 ReusableBuffer<byte> buf;
06252
06253 while ((num = FioReadWord()) != 0) {
06254 byte type = FioReadByte();
06255 _nfo_line++;
06256
06257 if (type == 0xFF) {
06258 if (_skip_sprites == 0) {
06259 DecodeSpecialSprite(buf.Allocate(num), num, stage);
06260
06261
06262 if (_skip_sprites == -1) break;
06263
06264 continue;
06265 } else {
06266 FioSkipBytes(num);
06267 }
06268 } else {
06269 if (_skip_sprites == 0) {
06270 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
06271 config->status = GCS_DISABLED;
06272 config->error = CallocT<GRFError>(1);
06273 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06274 config->error->message = STR_NEWGRF_ERROR_UNEXPECTED_SPRITE;
06275 break;
06276 }
06277
06278 FioSkipBytes(7);
06279 SkipSpriteData(type, num - 8);
06280 }
06281
06282 if (_skip_sprites > 0) _skip_sprites--;
06283 }
06284 }
06285
06293 static void ActivateOldShore()
06294 {
06295
06296
06297 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06298
06299 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
06300 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
06301 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
06302 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
06303 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
06304 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
06305 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
06306 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
06307 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
06308 }
06309
06310 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
06311 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
06312 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
06313 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
06314 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
06315 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
06316 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
06317 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
06318 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
06319
06320
06321
06322 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
06323 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
06324 }
06325 }
06326
06330 static void FinalisePriceBaseMultipliers()
06331 {
06332 extern const PriceBaseSpec _price_base_specs[];
06333 static const uint32 override_features = (1 << GSF_TRAIN) | (1 << GSF_ROAD) | (1 << GSF_SHIP) | (1 << GSF_AIRCRAFT);
06334
06335
06336 int num_grfs = _grf_files.Length();
06337 int *grf_overrides = AllocaM(int, num_grfs);
06338 for (int i = 0; i < num_grfs; i++) {
06339 grf_overrides[i] = -1;
06340
06341 GRFFile *source = _grf_files[i];
06342 uint32 override = _grf_id_overrides[source->grfid];
06343 if (override == 0) continue;
06344
06345 GRFFile *dest = GetFileByGRFID(override);
06346 if (dest == NULL) continue;
06347
06348 grf_overrides[i] = _grf_files.FindIndex(dest);
06349 assert(grf_overrides[i] >= 0);
06350 }
06351
06352
06353 for (int i = 0; i < num_grfs; i++) {
06354 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
06355 GRFFile *source = _grf_files[i];
06356 GRFFile *dest = _grf_files[grf_overrides[i]];
06357
06358 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06359 source->grf_features |= features;
06360 dest->grf_features |= features;
06361
06362 for (Price p = PR_BEGIN; p < PR_END; p++) {
06363
06364 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
06365 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
06366 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06367 }
06368 }
06369
06370
06371 for (int i = num_grfs - 1; i >= 0; i--) {
06372 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
06373 GRFFile *source = _grf_files[i];
06374 GRFFile *dest = _grf_files[grf_overrides[i]];
06375
06376 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06377 source->grf_features |= features;
06378 dest->grf_features |= features;
06379
06380 for (Price p = PR_BEGIN; p < PR_END; p++) {
06381
06382 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
06383 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
06384 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06385 }
06386 }
06387
06388
06389 for (int i = 0; i < num_grfs; i++) {
06390 if (grf_overrides[i] < 0) continue;
06391 GRFFile *source = _grf_files[i];
06392 GRFFile *dest = _grf_files[grf_overrides[i]];
06393
06394 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06395 source->grf_features |= features;
06396 dest->grf_features |= features;
06397
06398 for (Price p = PR_BEGIN; p < PR_END; p++) {
06399 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
06400 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
06401 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
06402 }
06403 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
06404 }
06405 }
06406
06407
06408 const GRFFile * const *end = _grf_files.End();
06409 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06410 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06411 for (Price p = PR_BEGIN; p < PR_END; p++) {
06412 Price fallback_price = _price_base_specs[p].fallback_price;
06413 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06414
06415
06416 price_base_multipliers[p] = price_base_multipliers[fallback_price];
06417 }
06418 }
06419 }
06420
06421
06422 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06423 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06424 for (Price p = PR_BEGIN; p < PR_END; p++) {
06425 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06426
06427 price_base_multipliers[p] = 0;
06428 } else {
06429 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
06430
06431
06432 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
06433 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
06434 price_base_multipliers[p] = 0;
06435 } else {
06436 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
06437 }
06438 }
06439 }
06440 }
06441 }
06442
06443 void InitDepotWindowBlockSizes();
06444
06445 extern void InitGRFTownGeneratorNames();
06446
06447 static void AfterLoadGRFs()
06448 {
06449 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
06450 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
06451 }
06452 _string_to_grf_mapping.clear();
06453
06454
06455 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
06456 free((*it).second);
06457 }
06458 _grf_line_to_action6_sprite_override.clear();
06459
06460
06461 CalculateRefitMasks();
06462
06463
06464 InitDepotWindowBlockSizes();
06465
06466
06467 FinaliseHouseArray();
06468
06469
06470 FinaliseIndustriesArray();
06471
06472
06473 BuildIndustriesLegend();
06474
06475
06476 InitGRFTownGeneratorNames();
06477
06478
06479 CommitVehicleListOrderChanges();
06480
06481
06482 ActivateOldShore();
06483
06484
06485 InitRailTypes();
06486
06487 Engine *e;
06488 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
06489 if (_gted[e->index].rv_max_speed != 0) {
06490
06491 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
06492 }
06493 }
06494
06495 SetYearEngineAgingStops();
06496
06497 FinalisePriceBaseMultipliers();
06498
06499
06500 free(_gted);
06501 _grm_sprites.clear();
06502 }
06503
06504 void LoadNewGRF(uint load_index, uint file_index)
06505 {
06506
06507
06508
06509
06510 Date date = _date;
06511 Year year = _cur_year;
06512 DateFract date_fract = _date_fract;
06513 uint16 tick_counter = _tick_counter;
06514 byte display_opt = _display_opt;
06515
06516 if (_networking) {
06517 _cur_year = _settings_game.game_creation.starting_year;
06518 _date = ConvertYMDToDate(_cur_year, 0, 1);
06519 _date_fract = 0;
06520 _tick_counter = 0;
06521 _display_opt = 0;
06522 }
06523
06524 InitializeGRFSpecial();
06525
06526 ResetNewGRFData();
06527
06528
06529
06530
06531
06532
06533
06534
06535 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06536 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
06537 }
06538
06539 _cur_spriteid = load_index;
06540
06541
06542
06543
06544 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
06545
06546
06547 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06548 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
06549 }
06550
06551 uint slot = file_index;
06552
06553 _cur_stage = stage;
06554 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06555 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
06556 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
06557
06558 if (!FioCheckFileExists(c->filename)) {
06559 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
06560 c->status = GCS_NOT_FOUND;
06561 continue;
06562 }
06563
06564 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
06565 LoadNewGRFFile(c, slot++, stage);
06566 if (stage == GLS_RESERVE) {
06567 SetBit(c->flags, GCF_RESERVED);
06568 } else if (stage == GLS_ACTIVATION) {
06569 ClrBit(c->flags, GCF_RESERVED);
06570 assert(GetFileByGRFID(c->grfid) == _cur_grffile);
06571 ClearTemporaryNewGRFData(_cur_grffile);
06572 BuildCargoTranslationMap();
06573 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
06574 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
06575
06576 ClearTemporaryNewGRFData(_cur_grffile);
06577 }
06578 }
06579 }
06580
06581
06582 AfterLoadGRFs();
06583
06584
06585 _cur_year = year;
06586 _date = date;
06587 _date_fract = date_fract;
06588 _tick_counter = tick_counter;
06589 _display_opt = display_opt;
06590 }
06591
06592 bool HasGrfMiscBit(GrfMiscBit bit)
06593 {
06594 return HasBit(_misc_grf_features, bit);
06595 }