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 PROP_AIRCRAFT_PASSENGER_CAPACITY:
01052 avi->passenger_capacity = buf->ReadWord();
01053 break;
01054
01055 case PROP_AIRCRAFT_MAIL_CAPACITY:
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->ReadWord();
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 case 0x16:
02586 rti->map_colour = MapDOSColour(buf->ReadByte());
02587 break;
02588
02589 default:
02590 ret = CIR_UNKNOWN;
02591 break;
02592 }
02593 }
02594
02595 return ret;
02596 }
02597
02598 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
02599 {
02600 ChangeInfoResult ret = CIR_SUCCESS;
02601
02602 if (id + numinfo > RAILTYPE_END) {
02603 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
02604 return CIR_INVALID_ID;
02605 }
02606
02607 for (int i = 0; i < numinfo; i++) {
02608 switch (prop) {
02609 case 0x08:
02610 {
02611 RailTypeLabel rtl = buf->ReadDWord();
02612 rtl = BSWAP32(rtl);
02613
02614 RailType rt = GetRailTypeByLabel(rtl);
02615 if (rt == INVALID_RAILTYPE) {
02616
02617 rt = AllocateRailType(rtl);
02618 }
02619
02620 _cur_grffile->railtype_map[id + i] = rt;
02621 break;
02622 }
02623
02624 case 0x09:
02625 case 0x0A:
02626 case 0x0B:
02627 case 0x0C:
02628 case 0x0D:
02629 case 0x13:
02630 case 0x14:
02631 buf->ReadWord();
02632 break;
02633
02634 case 0x0E:
02635 case 0x0F:
02636 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
02637 break;
02638
02639 case 0x10:
02640 case 0x11:
02641 case 0x12:
02642 case 0x15:
02643 case 0x16:
02644 buf->ReadByte();
02645 break;
02646
02647 default:
02648 ret = CIR_UNKNOWN;
02649 break;
02650 }
02651 }
02652
02653 return ret;
02654 }
02655
02656 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
02657 {
02658 switch (cir) {
02659 default: NOT_REACHED();
02660
02661 case CIR_SUCCESS:
02662 return false;
02663
02664 case CIR_UNHANDLED:
02665 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
02666 return false;
02667
02668 case CIR_UNKNOWN:
02669 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
02670
02671
02672 case CIR_INVALID_ID:
02673
02674 _skip_sprites = -1;
02675 _cur_grfconfig->status = GCS_DISABLED;
02676 delete _cur_grfconfig->error;
02677 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL);
02678 _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY;
02679 return true;
02680 }
02681 }
02682
02683
02684 static void FeatureChangeInfo(ByteReader *buf)
02685 {
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697 static const VCI_Handler handler[] = {
02698 RailVehicleChangeInfo,
02699 RoadVehicleChangeInfo,
02700 ShipVehicleChangeInfo,
02701 AircraftVehicleChangeInfo,
02702 StationChangeInfo,
02703 CanalChangeInfo,
02704 BridgeChangeInfo,
02705 TownHouseChangeInfo,
02706 GlobalVarChangeInfo,
02707 IndustrytilesChangeInfo,
02708 IndustriesChangeInfo,
02709 NULL,
02710 SoundEffectChangeInfo,
02711 NULL,
02712 NULL,
02713 NULL,
02714 RailTypeChangeInfo,
02715 };
02716
02717 uint8 feature = buf->ReadByte();
02718 uint8 numprops = buf->ReadByte();
02719 uint numinfo = buf->ReadByte();
02720 uint engine = buf->ReadExtended();
02721
02722 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
02723 feature, numprops, engine, numinfo);
02724
02725 if (feature >= lengthof(handler) || handler[feature] == NULL) {
02726 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
02727 return;
02728 }
02729
02730
02731 SetBit(_cur_grffile->grf_features, feature);
02732
02733 while (numprops-- && buf->HasData()) {
02734 uint8 prop = buf->ReadByte();
02735
02736 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
02737 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
02738 }
02739 }
02740
02741
02742 static void SafeChangeInfo(ByteReader *buf)
02743 {
02744 uint8 feature = buf->ReadByte();
02745 uint8 numprops = buf->ReadByte();
02746 uint numinfo = buf->ReadByte();
02747 buf->ReadExtended();
02748
02749 if (feature == GSF_BRIDGE && numprops == 1) {
02750 uint8 prop = buf->ReadByte();
02751
02752
02753 if (prop == 0x0D) return;
02754 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
02755 uint8 prop = buf->ReadByte();
02756
02757 if (prop == 0x11) {
02758 bool is_safe = true;
02759 for (uint i = 0; i < numinfo; i++) {
02760 uint32 s = buf->ReadDWord();
02761 buf->ReadDWord();
02762 const GRFConfig *grfconfig = GetGRFConfig(s);
02763 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
02764 is_safe = false;
02765 break;
02766 }
02767 }
02768 if (is_safe) return;
02769 }
02770 }
02771
02772 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
02773
02774
02775 _skip_sprites = -1;
02776 }
02777
02778
02779 static void ReserveChangeInfo(ByteReader *buf)
02780 {
02781 uint8 feature = buf->ReadByte();
02782
02783 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
02784
02785 uint8 numprops = buf->ReadByte();
02786 uint8 numinfo = buf->ReadByte();
02787 uint8 index = buf->ReadExtended();
02788
02789 while (numprops-- && buf->HasData()) {
02790 uint8 prop = buf->ReadByte();
02791 ChangeInfoResult cir = CIR_SUCCESS;
02792
02793 switch (feature) {
02794 default: NOT_REACHED();
02795 case GSF_CARGOS:
02796 cir = CargoChangeInfo(index, numinfo, prop, buf);
02797 break;
02798
02799 case GSF_GLOBALVAR:
02800 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
02801 break;
02802
02803 case GSF_RAILTYPES:
02804 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
02805 break;
02806 }
02807
02808 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
02809 }
02810 }
02811
02812
02813 static void NewSpriteSet(ByteReader *buf)
02814 {
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827 uint8 feature = buf->ReadByte();
02828 uint8 num_sets = buf->ReadByte();
02829 uint16 num_ents = buf->ReadExtended();
02830
02831 _cur_grffile->spriteset_start = _cur_spriteid;
02832 _cur_grffile->spriteset_feature = feature;
02833 _cur_grffile->spriteset_numsets = num_sets;
02834 _cur_grffile->spriteset_numents = num_ents;
02835
02836 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
02837 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
02838 );
02839
02840 for (int i = 0; i < num_sets * num_ents; i++) {
02841 _nfo_line++;
02842 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
02843 }
02844 }
02845
02846
02847 static void SkipAct1(ByteReader *buf)
02848 {
02849 buf->ReadByte();
02850 uint8 num_sets = buf->ReadByte();
02851 uint16 num_ents = buf->ReadExtended();
02852
02853 _skip_sprites = num_sets * num_ents;
02854
02855 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
02856 }
02857
02858
02859
02860 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
02861 {
02862 if (HasBit(groupid, 15)) return new CallbackResultSpriteGroup(groupid);
02863
02864 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
02865 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
02866 return NULL;
02867 }
02868
02869 return _cur_grffile->spritegroups[groupid];
02870 }
02871
02872
02873 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
02874 {
02875 if (HasBit(spriteid, 15)) return new CallbackResultSpriteGroup(spriteid);
02876
02877 if (spriteid >= _cur_grffile->spriteset_numsets) {
02878 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
02879 return NULL;
02880 }
02881
02882
02883
02884
02885 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
02886 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
02887 setid, type,
02888 _cur_grffile->spriteset_start + spriteid * num_sprites,
02889 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
02890 return NULL;
02891 }
02892
02893 if (feature != _cur_grffile->spriteset_feature) {
02894 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
02895 setid, type,
02896 _cur_grffile->spriteset_feature, feature);
02897 return NULL;
02898 }
02899
02900 return new ResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
02901 }
02902
02903
02904 static void NewSpriteGroup(ByteReader *buf)
02905 {
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916 SpriteGroup *act_group = NULL;
02917
02918 uint8 feature = buf->ReadByte();
02919 uint8 setid = buf->ReadByte();
02920 uint8 type = buf->ReadByte();
02921
02922 if (setid >= _cur_grffile->spritegroups_count) {
02923
02924 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
02925
02926 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++) {
02927 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
02928 }
02929 }
02930
02931
02932
02933
02934
02935 switch (type) {
02936
02937 case 0x81:
02938 case 0x82:
02939 case 0x85:
02940 case 0x86:
02941 case 0x89:
02942 case 0x8A:
02943 {
02944 byte varadjust;
02945 byte varsize;
02946
02947 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
02948 act_group = group;
02949 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
02950
02951 switch (GB(type, 2, 2)) {
02952 default: NOT_REACHED();
02953 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
02954 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
02955 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
02956 }
02957
02958
02959
02960 do {
02961 DeterministicSpriteGroupAdjust *adjust;
02962
02963 group->num_adjusts++;
02964 group->adjusts = ReallocT(group->adjusts, group->num_adjusts);
02965
02966 adjust = &group->adjusts[group->num_adjusts - 1];
02967
02968
02969 adjust->operation = group->num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
02970 adjust->variable = buf->ReadByte();
02971 if (adjust->variable == 0x7E) {
02972
02973 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
02974 } else {
02975 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
02976 }
02977
02978 varadjust = buf->ReadByte();
02979 adjust->shift_num = GB(varadjust, 0, 5);
02980 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
02981 adjust->and_mask = buf->ReadVarSize(varsize);
02982
02983 if (adjust->type != DSGA_TYPE_NONE) {
02984 adjust->add_val = buf->ReadVarSize(varsize);
02985 adjust->divmod_val = buf->ReadVarSize(varsize);
02986 } else {
02987 adjust->add_val = 0;
02988 adjust->divmod_val = 0;
02989 }
02990
02991
02992 } while (HasBit(varadjust, 5));
02993
02994 group->num_ranges = buf->ReadByte();
02995 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
02996
02997 for (uint i = 0; i < group->num_ranges; i++) {
02998 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
02999 group->ranges[i].low = buf->ReadVarSize(varsize);
03000 group->ranges[i].high = buf->ReadVarSize(varsize);
03001 }
03002
03003 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
03004 break;
03005 }
03006
03007
03008 case 0x80:
03009 case 0x83:
03010 case 0x84:
03011 {
03012 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
03013 act_group = group;
03014 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03015
03016 if (HasBit(type, 2)) {
03017 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
03018 group->count = buf->ReadByte();
03019 }
03020
03021 uint8 triggers = buf->ReadByte();
03022 group->triggers = GB(triggers, 0, 7);
03023 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
03024 group->lowest_randbit = buf->ReadByte();
03025 group->num_groups = buf->ReadByte();
03026 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
03027
03028 for (uint i = 0; i < group->num_groups; i++) {
03029 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
03030 }
03031
03032 break;
03033 }
03034
03035
03036 default:
03037 {
03038 switch (feature) {
03039 case GSF_TRAIN:
03040 case GSF_ROAD:
03041 case GSF_SHIP:
03042 case GSF_AIRCRAFT:
03043 case GSF_STATION:
03044 case GSF_CANAL:
03045 case GSF_CARGOS:
03046 case GSF_RAILTYPES:
03047 {
03048 byte sprites = _cur_grffile->spriteset_numents;
03049 byte num_loaded = type;
03050 byte num_loading = buf->ReadByte();
03051
03052 if (_cur_grffile->spriteset_start == 0) {
03053 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
03054 return;
03055 }
03056
03057 RealSpriteGroup *group = new RealSpriteGroup();
03058 act_group = group;
03059
03060 group->num_loaded = num_loaded;
03061 group->num_loading = num_loading;
03062 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
03063 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
03064
03065 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
03066 setid, sprites, num_loaded, num_loading);
03067
03068 for (uint i = 0; i < num_loaded; i++) {
03069 uint16 spriteid = buf->ReadWord();
03070 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03071 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
03072 }
03073
03074 for (uint i = 0; i < num_loading; i++) {
03075 uint16 spriteid = buf->ReadWord();
03076 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03077 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
03078 }
03079
03080 break;
03081 }
03082
03083 case GSF_TOWNHOUSE:
03084 case GSF_INDUSTRYTILES: {
03085 byte num_spriteset_ents = _cur_grffile->spriteset_numents;
03086 byte num_spritesets = _cur_grffile->spriteset_numsets;
03087 byte num_building_sprites = max((uint8)1, type);
03088 uint i;
03089
03090 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
03091 act_group = group;
03092
03093 group->num_building_stages = max((uint8)1, num_spriteset_ents);
03094 group->dts = CallocT<DrawTileSprites>(1);
03095
03096
03097 group->dts->ground.sprite = buf->ReadWord();
03098 group->dts->ground.pal = buf->ReadWord();
03099
03100
03101 MapSpriteMappingRecolour(&group->dts->ground);
03102
03103 if (HasBit(group->dts->ground.pal, 15)) {
03104
03105
03106 uint spriteset = GB(group->dts->ground.sprite, 0, 14);
03107 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03108 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03109 group->dts->ground.sprite = SPR_IMG_QUERY;
03110 group->dts->ground.pal = PAL_NONE;
03111 } else {
03112 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03113 SB(group->dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
03114 ClrBit(group->dts->ground.pal, 15);
03115 SetBit(group->dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03116 }
03117 }
03118
03119 group->dts->seq = CallocT<DrawTileSeqStruct>(num_building_sprites + 1);
03120
03121 for (i = 0; i < num_building_sprites; i++) {
03122 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts->seq[i]);
03123
03124 seq->image.sprite = buf->ReadWord();
03125 seq->image.pal = buf->ReadWord();
03126 seq->delta_x = buf->ReadByte();
03127 seq->delta_y = buf->ReadByte();
03128
03129 MapSpriteMappingRecolour(&seq->image);
03130
03131 if (HasBit(seq->image.pal, 15)) {
03132
03133
03134 uint spriteset = GB(seq->image.sprite, 0, 14);
03135 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03136 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03137 seq->image.sprite = SPR_IMG_QUERY;
03138 seq->image.pal = PAL_NONE;
03139 } else {
03140 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03141 SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
03142 ClrBit(seq->image.pal, 15);
03143 SetBit(seq->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03144 }
03145 }
03146
03147 if (type > 0) {
03148 seq->delta_z = buf->ReadByte();
03149 if ((byte)seq->delta_z == 0x80) continue;
03150 }
03151
03152 seq->size_x = buf->ReadByte();
03153 seq->size_y = buf->ReadByte();
03154 seq->size_z = buf->ReadByte();
03155 }
03156
03157
03158 const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].delta_x = (int8)0x80;
03159
03160 break;
03161 }
03162
03163 case GSF_INDUSTRIES: {
03164 if (type > 1) {
03165 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
03166 break;
03167 }
03168
03169 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
03170 act_group = group;
03171 group->version = type;
03172 if (type == 0) {
03173 for (uint i = 0; i < 3; i++) {
03174 group->subtract_input[i] = (int16)buf->ReadWord();
03175 }
03176 for (uint i = 0; i < 2; i++) {
03177 group->add_output[i] = buf->ReadWord();
03178 }
03179 group->again = buf->ReadByte();
03180 } else {
03181 for (uint i = 0; i < 3; i++) {
03182 group->subtract_input[i] = buf->ReadByte();
03183 }
03184 for (uint i = 0; i < 2; i++) {
03185 group->add_output[i] = buf->ReadByte();
03186 }
03187 group->again = buf->ReadByte();
03188 }
03189 break;
03190 }
03191
03192
03193 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
03194 }
03195 }
03196 }
03197
03198 _cur_grffile->spritegroups[setid] = act_group;
03199 }
03200
03201 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
03202 {
03203
03204 if (feature == GSF_STATION && ctype == 0xFE) return CT_DEFAULT_NA;
03205 if (ctype == 0xFF) return CT_PURCHASE;
03206
03207 if (_cur_grffile->cargo_max == 0) {
03208
03209 if (ctype >= 32) {
03210 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
03211 return CT_INVALID;
03212 }
03213
03214 const CargoSpec *cs;
03215 FOR_ALL_CARGOSPECS(cs) {
03216 if (cs->bitnum == ctype) {
03217 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
03218 return cs->Index();
03219 }
03220 }
03221
03222 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
03223 return CT_INVALID;
03224 }
03225
03226
03227 if (ctype >= _cur_grffile->cargo_max) {
03228 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
03229 return CT_INVALID;
03230 }
03231
03232
03233 CargoLabel cl = _cur_grffile->cargo_list[ctype];
03234 if (cl == 0) {
03235 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
03236 return CT_INVALID;
03237 }
03238
03239 ctype = GetCargoIDByLabel(cl);
03240 if (ctype == CT_INVALID) {
03241 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));
03242 return CT_INVALID;
03243 }
03244
03245 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);
03246 return ctype;
03247 }
03248
03249
03250 static bool IsValidGroupID(uint16 groupid, const char *function)
03251 {
03252 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03253 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
03254 return false;
03255 }
03256
03257 return true;
03258 }
03259
03260 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
03261 {
03262 static EngineID *last_engines;
03263 static uint last_engines_count;
03264 bool wagover = false;
03265
03266
03267 if (HasBit(idcount, 7)) {
03268 wagover = true;
03269
03270 idcount = GB(idcount, 0, 7);
03271
03272 if (last_engines_count == 0) {
03273 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
03274 return;
03275 }
03276
03277 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
03278 last_engines_count, idcount);
03279 } else {
03280 if (last_engines_count != idcount) {
03281 last_engines = ReallocT(last_engines, idcount);
03282 last_engines_count = idcount;
03283 }
03284 }
03285
03286 EngineID *engines = AllocaM(EngineID, idcount);
03287 for (uint i = 0; i < idcount; i++) {
03288 engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, buf->ReadExtended())->index;
03289 if (!wagover) last_engines[i] = engines[i];
03290 }
03291
03292 uint8 cidcount = buf->ReadByte();
03293 for (uint c = 0; c < cidcount; c++) {
03294 uint8 ctype = buf->ReadByte();
03295 uint16 groupid = buf->ReadWord();
03296 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
03297
03298 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
03299
03300 ctype = TranslateCargo(feature, ctype);
03301 if (ctype == CT_INVALID) continue;
03302
03303 for (uint i = 0; i < idcount; i++) {
03304 EngineID engine = engines[i];
03305
03306 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
03307
03308 if (wagover) {
03309 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03310 } else {
03311 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
03312 }
03313 }
03314 }
03315
03316 uint16 groupid = buf->ReadWord();
03317 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
03318
03319 grfmsg(8, "-- Default group id 0x%04X", groupid);
03320
03321 for (uint i = 0; i < idcount; i++) {
03322 EngineID engine = engines[i];
03323
03324 if (wagover) {
03325 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03326 } else {
03327 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
03328 SetEngineGRF(engine, _cur_grffile);
03329 }
03330 }
03331 }
03332
03333
03334 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
03335 {
03336 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
03337 for (uint i = 0; i < idcount; i++) {
03338 cfs[i] = (CanalFeature)buf->ReadByte();
03339 }
03340
03341 uint8 cidcount = buf->ReadByte();
03342 buf->Skip(cidcount * 3);
03343
03344 uint16 groupid = buf->ReadWord();
03345 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
03346
03347 for (uint i = 0; i < idcount; i++) {
03348 CanalFeature cf = cfs[i];
03349
03350 if (cf >= CF_END) {
03351 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
03352 continue;
03353 }
03354
03355 _water_feature[cf].grffile = _cur_grffile;
03356 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
03357 }
03358 }
03359
03360
03361 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
03362 {
03363 uint8 *stations = AllocaM(uint8, idcount);
03364 for (uint i = 0; i < idcount; i++) {
03365 stations[i] = buf->ReadByte();
03366 }
03367
03368 uint8 cidcount = buf->ReadByte();
03369 for (uint c = 0; c < cidcount; c++) {
03370 uint8 ctype = buf->ReadByte();
03371 uint16 groupid = buf->ReadWord();
03372 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
03373
03374 ctype = TranslateCargo(GSF_STATION, ctype);
03375 if (ctype == CT_INVALID) continue;
03376
03377 for (uint i = 0; i < idcount; i++) {
03378 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03379
03380 if (statspec == NULL) {
03381 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03382 continue;
03383 }
03384
03385 statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
03386 }
03387 }
03388
03389 uint16 groupid = buf->ReadWord();
03390 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
03391
03392 for (uint i = 0; i < idcount; i++) {
03393 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
03394
03395 if (statspec == NULL) {
03396 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03397 continue;
03398 }
03399
03400 statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
03401 statspec->grffile = _cur_grffile;
03402 statspec->localidx = stations[i];
03403 SetCustomStationSpec(statspec);
03404 }
03405 }
03406
03407
03408 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
03409 {
03410 uint8 *houses = AllocaM(uint8, idcount);
03411 for (uint i = 0; i < idcount; i++) {
03412 houses[i] = buf->ReadByte();
03413 }
03414
03415
03416 uint8 cidcount = buf->ReadByte();
03417 buf->Skip(cidcount * 3);
03418
03419 uint16 groupid = buf->ReadWord();
03420 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
03421
03422 if (_cur_grffile->housespec == NULL) {
03423 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
03424 return;
03425 }
03426
03427 for (uint i = 0; i < idcount; i++) {
03428 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
03429
03430 if (hs == NULL) {
03431 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
03432 continue;
03433 }
03434
03435 hs->spritegroup = _cur_grffile->spritegroups[groupid];
03436 }
03437 }
03438
03439 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
03440 {
03441 uint8 *industries = AllocaM(uint8, idcount);
03442 for (uint i = 0; i < idcount; i++) {
03443 industries[i] = buf->ReadByte();
03444 }
03445
03446
03447 uint8 cidcount = buf->ReadByte();
03448 buf->Skip(cidcount * 3);
03449
03450 uint16 groupid = buf->ReadWord();
03451 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
03452
03453 if (_cur_grffile->industryspec == NULL) {
03454 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
03455 return;
03456 }
03457
03458 for (uint i = 0; i < idcount; i++) {
03459 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
03460
03461 if (indsp == NULL) {
03462 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
03463 continue;
03464 }
03465
03466 indsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03467 }
03468 }
03469
03470 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
03471 {
03472 uint8 *indtiles = AllocaM(uint8, idcount);
03473 for (uint i = 0; i < idcount; i++) {
03474 indtiles[i] = buf->ReadByte();
03475 }
03476
03477
03478 uint8 cidcount = buf->ReadByte();
03479 buf->Skip(cidcount * 3);
03480
03481 uint16 groupid = buf->ReadWord();
03482 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
03483
03484 if (_cur_grffile->indtspec == NULL) {
03485 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
03486 return;
03487 }
03488
03489 for (uint i = 0; i < idcount; i++) {
03490 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
03491
03492 if (indtsp == NULL) {
03493 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
03494 continue;
03495 }
03496
03497 indtsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03498 }
03499 }
03500
03501 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
03502 {
03503 CargoID *cargos = AllocaM(CargoID, idcount);
03504 for (uint i = 0; i < idcount; i++) {
03505 cargos[i] = buf->ReadByte();
03506 }
03507
03508
03509 uint8 cidcount = buf->ReadByte();
03510 buf->Skip(cidcount * 3);
03511
03512 uint16 groupid = buf->ReadWord();
03513 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
03514
03515 for (uint i = 0; i < idcount; i++) {
03516 CargoID cid = cargos[i];
03517
03518 if (cid >= NUM_CARGO) {
03519 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
03520 continue;
03521 }
03522
03523 CargoSpec *cs = CargoSpec::Get(cid);
03524 cs->grffile = _cur_grffile;
03525 cs->group = _cur_grffile->spritegroups[groupid];
03526 }
03527 }
03528
03529 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
03530 {
03531 uint8 *railtypes = AllocaM(uint8, idcount);
03532 for (uint i = 0; i < idcount; i++) {
03533 railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
03534 }
03535
03536 uint8 cidcount = buf->ReadByte();
03537 for (uint c = 0; c < cidcount; c++) {
03538 uint8 ctype = buf->ReadByte();
03539 uint16 groupid = buf->ReadWord();
03540 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
03541
03542 if (ctype >= RTSG_END) continue;
03543
03544 extern RailtypeInfo _railtypes[RAILTYPE_END];
03545 for (uint i = 0; i < idcount; i++) {
03546 if (railtypes[i] != INVALID_RAILTYPE) {
03547 RailtypeInfo *rti = &_railtypes[railtypes[i]];
03548
03549 rti->group[ctype] = _cur_grffile->spritegroups[groupid];
03550 }
03551 }
03552 }
03553
03554
03555 buf->ReadWord();
03556 }
03557
03558
03559
03560 static void FeatureMapSpriteGroup(ByteReader *buf)
03561 {
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576 if (_cur_grffile->spritegroups == NULL) {
03577 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
03578 return;
03579 }
03580
03581 uint8 feature = buf->ReadByte();
03582 uint8 idcount = buf->ReadByte();
03583
03584
03585 if (idcount == 0) {
03586
03587 buf->ReadByte();
03588 uint16 groupid = buf->ReadWord();
03589
03590 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
03591
03592 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
03593 return;
03594 }
03595
03596
03597 SetBit(_cur_grffile->grf_features, feature);
03598
03599 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
03600
03601 switch (feature) {
03602 case GSF_TRAIN:
03603 case GSF_ROAD:
03604 case GSF_SHIP:
03605 case GSF_AIRCRAFT:
03606 VehicleMapSpriteGroup(buf, feature, idcount);
03607 return;
03608
03609 case GSF_CANAL:
03610 CanalMapSpriteGroup(buf, idcount);
03611 return;
03612
03613 case GSF_STATION:
03614 StationMapSpriteGroup(buf, idcount);
03615 return;
03616
03617 case GSF_TOWNHOUSE:
03618 TownHouseMapSpriteGroup(buf, idcount);
03619 return;
03620
03621 case GSF_INDUSTRIES:
03622 IndustryMapSpriteGroup(buf, idcount);
03623 return;
03624
03625 case GSF_INDUSTRYTILES:
03626 IndustrytileMapSpriteGroup(buf, idcount);
03627 return;
03628
03629 case GSF_CARGOS:
03630 CargoMapSpriteGroup(buf, idcount);
03631 return;
03632
03633 case GSF_RAILTYPES:
03634 RailTypeMapSpriteGroup(buf, idcount);
03635 break;
03636
03637 default:
03638 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
03639 return;
03640 }
03641 }
03642
03643
03644 static void FeatureNewName(ByteReader *buf)
03645 {
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662 bool new_scheme = _cur_grffile->grf_version >= 7;
03663
03664 uint8 feature = buf->ReadByte();
03665 uint8 lang = buf->ReadByte();
03666 uint8 num = buf->ReadByte();
03667 bool generic = HasBit(lang, 7);
03668 uint16 id;
03669 if (generic) {
03670 id = buf->ReadWord();
03671 } else if (feature <= GSF_AIRCRAFT) {
03672 id = buf->ReadExtended();
03673 } else {
03674 id = buf->ReadByte();
03675 }
03676
03677 ClrBit(lang, 7);
03678
03679 uint16 endid = id + num;
03680
03681 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
03682 id, endid, feature, lang);
03683
03684 for (; id < endid && buf->HasData(); id++) {
03685 const char *name = buf->ReadString();
03686 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
03687
03688 switch (feature) {
03689 case GSF_TRAIN:
03690 case GSF_ROAD:
03691 case GSF_SHIP:
03692 case GSF_AIRCRAFT:
03693 if (!generic) {
03694 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
03695 if (e == NULL) break;
03696 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
03697 e->info.string_id = string;
03698 } else {
03699 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03700 }
03701 break;
03702
03703 case GSF_INDUSTRIES: {
03704 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03705 break;
03706 }
03707
03708 case GSF_TOWNHOUSE:
03709 default:
03710 switch (GB(id, 8, 8)) {
03711 case 0xC4:
03712 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03713 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03714 } else {
03715 StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass;
03716 SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
03717 }
03718 break;
03719
03720 case 0xC5:
03721 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03722 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03723 } else {
03724 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03725 }
03726 break;
03727
03728 case 0xC9:
03729 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
03730 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
03731 } else {
03732 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03733 }
03734 break;
03735
03736 case 0xD0:
03737 case 0xD1:
03738 case 0xD2:
03739 case 0xD3:
03740 case 0xDC:
03741 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03742 break;
03743
03744 default:
03745 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03746 break;
03747 }
03748 break;
03749
03750 #if 0
03751 case GSF_CANAL :
03752 case GSF_BRIDGE :
03753 AddGRFString(_cur_spriteid, id, lang, name);
03754 switch (GB(id, 8, 8)) {
03755 case 0xC9:
03756 default:
03757 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03758 }
03759 break;
03760
03761 default :
03762 grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature);
03763 break;
03764 #endif
03765 }
03766 }
03767 }
03768
03777 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
03778 {
03779
03780 if (offset >= max_sprites) {
03781 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
03782 uint orig_num = num;
03783 num = 0;
03784 return orig_num;
03785 }
03786
03787 if (offset + num > max_sprites) {
03788 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
03789 uint orig_num = num;
03790 num = max(max_sprites - offset, 0);
03791 return orig_num - num;
03792 }
03793
03794 return 0;
03795 }
03796
03797
03798 static void GraphicsNew(ByteReader *buf)
03799 {
03800
03801
03802
03803
03804
03805
03806
03807 enum Action5BlockType {
03808 A5BLOCK_FIXED,
03809 A5BLOCK_ALLOW_OFFSET,
03810 A5BLOCK_INVALID,
03811 };
03812 struct Action5Type {
03813 Action5BlockType block_type;
03814 SpriteID sprite_base;
03815 uint16 min_sprites;
03816 uint16 max_sprites;
03817 const char *name;
03818 };
03819
03820 static const Action5Type action5_types[] = {
03821
03822 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
03823 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
03824 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
03825 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
03826 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
03827 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
03828 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
03829 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
03830 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
03831 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
03832 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
03833 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
03834 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
03835 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
03836 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
03837 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
03838 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
03839 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
03840 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
03841 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
03842 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
03843 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
03844 };
03845
03846 uint8 type = buf->ReadByte();
03847 uint16 num = buf->ReadExtended();
03848 uint16 offset = HasBit(type, 7) ? buf->ReadExtended() : 0;
03849 ClrBit(type, 7);
03850
03851 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
03852
03853
03854 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from openttd(d/w).grf.");
03855 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
03856 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
03857 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
03858 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
03859 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
03860 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
03861 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
03862 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
03863 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
03864 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
03865 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
03866 return;
03867 }
03868
03869
03870 if ((type >= lengthof(action5_types)) || (action5_types[type].block_type == A5BLOCK_INVALID)) {
03871 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
03872 _skip_sprites = num;
03873 return;
03874 }
03875
03876 const Action5Type *action5_type = &action5_types[type];
03877
03878
03879 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
03880 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
03881 offset = 0;
03882 }
03883
03884
03885
03886 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
03887 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);
03888 _skip_sprites = num;
03889 return;
03890 }
03891
03892
03893 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
03894 SpriteID replace = action5_type->sprite_base + offset;
03895
03896
03897 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);
03898
03899 for (; num > 0; num--) {
03900 _nfo_line++;
03901 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
03902 }
03903
03904 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
03905
03906 _skip_sprites = skip_num;
03907 }
03908
03909
03910 static void SkipAct5(ByteReader *buf)
03911 {
03912
03913 buf->ReadByte();
03914
03915
03916 _skip_sprites = buf->ReadExtended();
03917
03918 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
03919 }
03920
03931 bool GetGlobalVariable(byte param, uint32 *value)
03932 {
03933 switch (param) {
03934 case 0x00:
03935 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
03936 return true;
03937
03938 case 0x01:
03939 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
03940 return true;
03941
03942 case 0x02: {
03943 YearMonthDay ymd;
03944 ConvertDateToYMD(_date, &ymd);
03945 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
03946 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
03947 return true;
03948 }
03949
03950 case 0x03:
03951 *value = _settings_game.game_creation.landscape;
03952 return true;
03953
03954 case 0x06:
03955 *value = _settings_game.vehicle.road_side << 4;
03956 return true;
03957
03958 case 0x09:
03959 *value = _date_fract * 885;
03960 return true;
03961
03962 case 0x0A:
03963 *value = _tick_counter;
03964 return true;
03965
03966 case 0x0B: {
03967 uint major = 2;
03968 uint minor = 6;
03969 uint revision = 1;
03970 uint build = 1382;
03971 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
03972 return true;
03973 }
03974
03975 case 0x0D:
03976 *value = _cur_grfconfig->windows_paletted;
03977 return true;
03978
03979 case 0x0E:
03980 *value = _cur_grffile->traininfo_vehicle_pitch;
03981 return true;
03982
03983 case 0x0F:
03984 *value = 0;
03985 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
03986 if (_settings_game.vehicle.disable_elrails) {
03987
03988 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
03989 } else {
03990 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
03991
03992 }
03993 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
03994 return true;
03995
03996 case 0x11:
03997 *value = 0;
03998 return true;
03999
04000 case 0x12:
04001 *value = _game_mode;
04002 return true;
04003
04004
04005
04006
04007
04008
04009
04010 case 0x1A:
04011 *value = UINT_MAX;
04012 return true;
04013
04014 case 0x1B:
04015 *value = GB(_display_opt, 0, 6);
04016 return true;
04017
04018 case 0x1D:
04019 *value = 1;
04020 return true;
04021
04022 case 0x1E:
04023 *value = _misc_grf_features;
04024
04025
04026 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
04027 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
04028 return true;
04029
04030
04031
04032 case 0x20:
04033 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
04034 return true;
04035
04036 case 0x21:
04037 *value = _openttd_newgrf_version;
04038 return true;
04039
04040 case 0x22:
04041 *value = _settings_game.difficulty.diff_level;
04042 return true;
04043
04044 case 0x23:
04045 *value = _date;
04046 return true;
04047
04048 case 0x24:
04049 *value = _cur_year;
04050 return true;
04051
04052 default: return false;
04053 }
04054 }
04055
04056 static uint32 GetParamVal(byte param, uint32 *cond_val)
04057 {
04058
04059 uint32 value;
04060 if (GetGlobalVariable(param - 0x80, &value)) return value;
04061
04062
04063 switch (param) {
04064 case 0x84: {
04065 uint32 res = 0;
04066
04067 if (_cur_stage > GLS_INIT) SetBit(res, 0);
04068 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
04069 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
04070 return res;
04071 }
04072
04073 case 0x85:
04074 if (cond_val == NULL) {
04075
04076 return 0;
04077 } else {
04078 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
04079 *cond_val %= 0x20;
04080 return param_val;
04081 }
04082
04083 case 0x88:
04084 return 0;
04085
04086
04087
04088 default:
04089
04090 if (param < 0x80) return _cur_grffile->GetParam(param);
04091
04092
04093 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
04094 return UINT_MAX;
04095 }
04096 }
04097
04098
04099 static void CfgApply(ByteReader *buf)
04100 {
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113 size_t pos = FioGetPos();
04114 uint16 num = FioReadWord();
04115 uint8 type = FioReadByte();
04116 byte *preload_sprite = NULL;
04117
04118
04119 if (type == 0xFF) {
04120 preload_sprite = MallocT<byte>(num);
04121 FioReadBlock(preload_sprite, num);
04122 }
04123
04124
04125 FioSeekTo(pos, SEEK_SET);
04126
04127 if (type != 0xFF) {
04128 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
04129 free(preload_sprite);
04130 return;
04131 }
04132
04133 GRFLocation location(_cur_grfconfig->grfid, _nfo_line + 1);
04134 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
04135 if (it != _grf_line_to_action6_sprite_override.end()) {
04136 free(preload_sprite);
04137 preload_sprite = _grf_line_to_action6_sprite_override[location];
04138 } else {
04139 _grf_line_to_action6_sprite_override[location] = preload_sprite;
04140 }
04141
04142
04143
04144 for (;;) {
04145 uint i;
04146 uint param_num;
04147 uint param_size;
04148 uint offset;
04149 bool add_value;
04150
04151
04152 param_num = buf->ReadByte();
04153 if (param_num == 0xFF) break;
04154
04155
04156
04157 param_size = buf->ReadByte();
04158
04159
04160
04161 add_value = HasBit(param_size, 7);
04162 param_size = GB(param_size, 0, 7);
04163
04164
04165 offset = buf->ReadExtended();
04166
04167
04168
04169 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
04170 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
04171 break;
04172 }
04173
04174 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
04175
04176 bool carry = false;
04177 for (i = 0; i < param_size && offset + i < num; i++) {
04178 uint32 value = GetParamVal(param_num + i / 4, NULL);
04179
04180
04181 if (i == 0) carry = false;
04182
04183 if (add_value) {
04184 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
04185 preload_sprite[offset + i] = GB(new_value, 0, 8);
04186
04187 carry = new_value >= 256;
04188 } else {
04189 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
04190 }
04191 }
04192 }
04193 }
04194
04204 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
04205 {
04206 delete c->error;
04207 c->status = GCS_DISABLED;
04208 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC);
04209 c->error->data = strdup(_cur_grfconfig->name);
04210
04211 ClearTemporaryNewGRFData(GetFileByGRFID(c->grfid));
04212 }
04213
04214
04215
04216 static void SkipIf(ByteReader *buf)
04217 {
04218
04219
04220
04221
04222
04223
04224
04225
04226 uint32 cond_val = 0;
04227 uint32 mask = 0;
04228 bool result;
04229
04230 uint8 param = buf->ReadByte();
04231 uint8 paramsize = buf->ReadByte();
04232 uint8 condtype = buf->ReadByte();
04233
04234 if (condtype < 2) {
04235
04236 paramsize = 1;
04237 }
04238
04239 switch (paramsize) {
04240 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
04241 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
04242 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
04243 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
04244 default: break;
04245 }
04246
04247 if (param < 0x80 && _cur_grffile->param_end <= param) {
04248 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
04249 return;
04250 }
04251
04252 uint32 param_val = GetParamVal(param, &cond_val);
04253
04254 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
04255
04256
04257
04258
04259
04260
04261
04262
04263 if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
04264
04265
04266 GRFConfig *c = GetGRFConfig(cond_val, mask);
04267
04268 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
04269 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04270 c = NULL;
04271 }
04272
04273 if (condtype != 10 && c == NULL) {
04274 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
04275 return;
04276 }
04277
04278 switch (condtype) {
04279
04280 case 0x06:
04281 result = c->status == GCS_ACTIVATED;
04282 break;
04283
04284 case 0x07:
04285 result = c->status != GCS_ACTIVATED;
04286 break;
04287
04288 case 0x08:
04289 result = c->status == GCS_INITIALISED;
04290 break;
04291
04292 case 0x09:
04293 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
04294 break;
04295
04296 case 0x0A:
04297
04298 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
04299 break;
04300
04301 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
04302 }
04303 } else {
04304
04305 switch (condtype) {
04306 case 0x00: result = !!(param_val & (1 << cond_val));
04307 break;
04308 case 0x01: result = !(param_val & (1 << cond_val));
04309 break;
04310 case 0x02: result = (param_val & mask) == cond_val;
04311 break;
04312 case 0x03: result = (param_val & mask) != cond_val;
04313 break;
04314 case 0x04: result = (param_val & mask) < cond_val;
04315 break;
04316 case 0x05: result = (param_val & mask) > cond_val;
04317 break;
04318 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
04319 break;
04320 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
04321 break;
04322 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
04323 break;
04324 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
04325 break;
04326
04327 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
04328 }
04329 }
04330
04331 if (!result) {
04332 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
04333 return;
04334 }
04335
04336 uint8 numsprites = buf->ReadByte();
04337
04338
04339
04340
04341
04342 GRFLabel *choice = NULL;
04343 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
04344 if (label->label != numsprites) continue;
04345
04346
04347 if (choice == NULL) choice = label;
04348
04349 if (label->nfo_line > _nfo_line) {
04350 choice = label;
04351 break;
04352 }
04353 }
04354
04355 if (choice != NULL) {
04356 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
04357 FioSeekTo(choice->pos, SEEK_SET);
04358 _nfo_line = choice->nfo_line;
04359 return;
04360 }
04361
04362 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
04363 _skip_sprites = numsprites;
04364 if (_skip_sprites == 0) {
04365
04366
04367
04368 _skip_sprites = -1;
04369
04370
04371 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
04372 _cur_grfconfig->status = GCS_DISABLED;
04373 ClearTemporaryNewGRFData(_cur_grffile);
04374 }
04375 }
04376 }
04377
04378
04379
04380 static void ScanInfo(ByteReader *buf)
04381 {
04382 buf->ReadByte();
04383 uint32 grfid = buf->ReadDWord();
04384
04385 _cur_grfconfig->grfid = grfid;
04386
04387
04388 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
04389
04390 const char *name = buf->ReadString();
04391 _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name);
04392
04393 if (buf->HasData()) {
04394 const char *info = buf->ReadString();
04395 _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info);
04396 }
04397
04398
04399 _skip_sprites = -1;
04400 }
04401
04402
04403 static void GRFInfo(ByteReader *buf)
04404 {
04405
04406
04407
04408
04409
04410
04411
04412 uint8 version = buf->ReadByte();
04413 uint32 grfid = buf->ReadDWord();
04414 const char *name = buf->ReadString();
04415
04416 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
04417 _cur_grfconfig->status = GCS_DISABLED;
04418 delete _cur_grfconfig->error;
04419 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
04420
04421 _skip_sprites = -1;
04422 return;
04423 }
04424
04425 _cur_grffile->grfid = grfid;
04426 _cur_grffile->grf_version = version;
04427 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
04428
04429
04430 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
04431 }
04432
04433
04434 static void SpriteReplace(ByteReader *buf)
04435 {
04436
04437
04438
04439
04440
04441
04442
04443
04444 uint8 num_sets = buf->ReadByte();
04445
04446 for (uint i = 0; i < num_sets; i++) {
04447 uint8 num_sprites = buf->ReadByte();
04448 uint16 first_sprite = buf->ReadWord();
04449
04450 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
04451 i, num_sprites, first_sprite
04452 );
04453
04454 for (uint j = 0; j < num_sprites; j++) {
04455 int load_index = first_sprite + j;
04456 _nfo_line++;
04457 LoadNextSprite(load_index, _file_index, _nfo_line);
04458
04459
04460
04461 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
04462 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
04463 }
04464 }
04465 }
04466 }
04467
04468
04469 static void SkipActA(ByteReader *buf)
04470 {
04471 uint8 num_sets = buf->ReadByte();
04472
04473 for (uint i = 0; i < num_sets; i++) {
04474
04475 _skip_sprites += buf->ReadByte();
04476
04477 buf->ReadWord();
04478 }
04479
04480 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
04481 }
04482
04483
04484 static void GRFLoadError(ByteReader *buf)
04485 {
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501 static const StringID msgstr[] = {
04502 STR_NEWGRF_ERROR_VERSION_NUMBER,
04503 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
04504 STR_NEWGRF_ERROR_UNSET_SWITCH,
04505 STR_NEWGRF_ERROR_INVALID_PARAMETER,
04506 STR_NEWGRF_ERROR_LOAD_BEFORE,
04507 STR_NEWGRF_ERROR_LOAD_AFTER,
04508 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
04509 };
04510
04511 static const StringID sevstr[] = {
04512 STR_NEWGRF_ERROR_MSG_INFO,
04513 STR_NEWGRF_ERROR_MSG_WARNING,
04514 STR_NEWGRF_ERROR_MSG_ERROR,
04515 STR_NEWGRF_ERROR_MSG_FATAL
04516 };
04517
04518
04519 if (_cur_grfconfig->error != NULL) return;
04520
04521 byte severity = buf->ReadByte();
04522 byte lang = buf->ReadByte();
04523 byte message_id = buf->ReadByte();
04524
04525
04526 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
04527
04528
04529
04530 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
04531 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
04532 return;
04533 }
04534 ClrBit(severity, 7);
04535
04536 if (severity >= lengthof(sevstr)) {
04537 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
04538 severity = 2;
04539 } else if (severity == 3) {
04540
04541
04542 _cur_grfconfig->status = GCS_DISABLED;
04543 ClearTemporaryNewGRFData(_cur_grffile);
04544 _skip_sprites = -1;
04545 }
04546
04547 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
04548 grfmsg(7, "GRFLoadError: Invalid message id.");
04549 return;
04550 }
04551
04552 if (buf->Remaining() <= 1) {
04553 grfmsg(7, "GRFLoadError: No message data supplied.");
04554 return;
04555 }
04556
04557 GRFError *error = new GRFError(sevstr[severity]);
04558
04559 if (message_id == 0xFF) {
04560
04561 if (buf->HasData()) {
04562 const char *message = buf->ReadString();
04563
04564 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, message);
04565 } else {
04566 grfmsg(7, "GRFLoadError: No custom message supplied.");
04567 error->custom_message = strdup("");
04568 }
04569 } else {
04570 error->message = msgstr[message_id];
04571 }
04572
04573 if (buf->HasData()) {
04574 const char *data = buf->ReadString();
04575
04576 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, data);
04577 } else {
04578 grfmsg(7, "GRFLoadError: No message data supplied.");
04579 error->data = strdup("");
04580 }
04581
04582
04583 uint i = 0;
04584 for (; i < 2 && buf->HasData(); i++) {
04585 uint param_number = buf->ReadByte();
04586 error->param_value[i] = _cur_grffile->GetParam(param_number);
04587 }
04588 error->num_params = i;
04589
04590 _cur_grfconfig->error = error;
04591 }
04592
04593
04594 static void GRFComment(ByteReader *buf)
04595 {
04596
04597
04598
04599
04600 if (!buf->HasData()) return;
04601
04602 const char *text = buf->ReadString();
04603 grfmsg(2, "GRFComment: %s", text);
04604 }
04605
04606
04607 static void SafeParamSet(ByteReader *buf)
04608 {
04609 uint8 target = buf->ReadByte();
04610
04611
04612 if (target < 0x80) return;
04613
04614
04615
04616
04617
04618
04619 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04620
04621
04622 _skip_sprites = -1;
04623 }
04624
04625
04626 static uint32 GetPatchVariable(uint8 param)
04627 {
04628 switch (param) {
04629
04630 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
04631
04632
04633 case 0x0E: return _settings_game.vehicle.freight_trains;
04634
04635
04636 case 0x0F: return 0;
04637
04638
04639
04640
04641 case 0x10:
04642 switch (_settings_game.vehicle.plane_speed) {
04643 default:
04644 case 4: return 1;
04645 case 3: return 2;
04646 case 2: return 2;
04647 case 1: return 4;
04648 }
04649
04650
04651
04652 case 0x11: return SPR_2CCMAP_BASE;
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662
04663
04664
04665 case 0x13: {
04666 byte map_bits = 0;
04667 byte log_X = MapLogX() - 6;
04668 byte log_Y = MapLogY() - 6;
04669 byte max_edge = max(log_X, log_Y);
04670
04671 if (log_X == log_Y) {
04672 SetBit(map_bits, 0);
04673 } else {
04674 if (max_edge == log_Y) SetBit(map_bits, 1);
04675 }
04676
04677 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
04678 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
04679 }
04680
04681 default:
04682 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
04683 return 0;
04684 }
04685 }
04686
04687
04688 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
04689 {
04690 uint start = 0;
04691 uint size = 0;
04692
04693 if (op == 6) {
04694
04695 return grm[_cur_grffile->GetParam(target)];
04696 }
04697
04698
04699 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
04700
04701 for (uint i = start; i < num_ids; i++) {
04702 if (grm[i] == 0) {
04703 size++;
04704 } else {
04705 if (op == 2 || op == 3) break;
04706 start = i + 1;
04707 size = 0;
04708 }
04709
04710 if (size == count) break;
04711 }
04712
04713 if (size == count) {
04714
04715 if (op == 0 || op == 3) {
04716 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
04717 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
04718 }
04719 return start;
04720 }
04721
04722
04723 if (op != 4 && op != 5) {
04724
04725 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
04726 _cur_grfconfig->status = GCS_DISABLED;
04727 ClearTemporaryNewGRFData(_cur_grffile);
04728 _skip_sprites = -1;
04729 return UINT_MAX;
04730 }
04731
04732 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
04733 return UINT_MAX;
04734 }
04735
04736
04737
04738 static void ParamSet(ByteReader *buf)
04739 {
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762 uint8 target = buf->ReadByte();
04763 uint8 oper = buf->ReadByte();
04764 uint32 src1 = buf->ReadByte();
04765 uint32 src2 = buf->ReadByte();
04766
04767 uint32 data = 0;
04768 if (buf->Remaining() >= 4) data = buf->ReadDWord();
04769
04770
04771
04772
04773
04774
04775
04776 if (HasBit(oper, 7)) {
04777 if (target < 0x80 && target < _cur_grffile->param_end) {
04778 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
04779 return;
04780 }
04781
04782 oper = GB(oper, 0, 7);
04783 }
04784
04785 if (src2 == 0xFE) {
04786 if (GB(data, 0, 8) == 0xFF) {
04787 if (data == 0x0000FFFF) {
04788
04789 src1 = GetPatchVariable(src1);
04790 } else {
04791
04792 uint8 op = src1;
04793 uint8 feature = GB(data, 8, 8);
04794 uint16 count = GB(data, 16, 16);
04795
04796 if (_cur_stage == GLS_RESERVE) {
04797 if (feature == 0x08) {
04798
04799 if (op == 0) {
04800
04801 if (_cur_spriteid + count >= 16384) {
04802 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
04803 _cur_grfconfig->status = GCS_DISABLED;
04804 ClearTemporaryNewGRFData(_cur_grffile);
04805 _skip_sprites = -1;
04806 return;
04807 }
04808
04809
04810 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
04811 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
04812 _cur_spriteid += count;
04813 }
04814 }
04815
04816 src1 = 0;
04817 } else if (_cur_stage == GLS_ACTIVATION) {
04818 switch (feature) {
04819 case 0x00:
04820 case 0x01:
04821 case 0x02:
04822 case 0x03:
04823 if (!_settings_game.vehicle.dynamic_engines) {
04824 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
04825 if (_skip_sprites == -1) return;
04826 } else {
04827
04828 switch (op) {
04829 case 2:
04830 case 3:
04831 src1 = _cur_grffile->GetParam(target);
04832 break;
04833
04834 default:
04835 src1 = 0;
04836 break;
04837 }
04838 }
04839 break;
04840
04841 case 0x08:
04842 switch (op) {
04843 case 0:
04844
04845 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
04846 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
04847 break;
04848
04849 case 1:
04850 src1 = _cur_spriteid;
04851 break;
04852
04853 default:
04854 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
04855 return;
04856 }
04857 break;
04858
04859 case 0x0B:
04860
04861 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
04862 if (_skip_sprites == -1) return;
04863 break;
04864
04865 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
04866 }
04867 } else {
04868
04869 src1 = 0;
04870 }
04871 }
04872 } else {
04873
04874 const GRFFile *file = GetFileByGRFID(data);
04875 GRFConfig *c = GetGRFConfig(data);
04876 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
04877
04878 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04879 src1 = 0;
04880 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
04881 src1 = 0;
04882 } else {
04883 src1 = file->GetParam(src1);
04884 }
04885 }
04886 } else {
04887
04888
04889
04890
04891
04892 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
04893 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
04894 }
04895
04896
04897
04898
04899
04900
04901
04902 uint32 res;
04903 switch (oper) {
04904 case 0x00:
04905 res = src1;
04906 break;
04907
04908 case 0x01:
04909 res = src1 + src2;
04910 break;
04911
04912 case 0x02:
04913 res = src1 - src2;
04914 break;
04915
04916 case 0x03:
04917 res = src1 * src2;
04918 break;
04919
04920 case 0x04:
04921 res = (int32)src1 * (int32)src2;
04922 break;
04923
04924 case 0x05:
04925 if ((int32)src2 < 0) {
04926 res = src1 >> -(int32)src2;
04927 } else {
04928 res = src1 << src2;
04929 }
04930 break;
04931
04932 case 0x06:
04933 if ((int32)src2 < 0) {
04934 res = (int32)src1 >> -(int32)src2;
04935 } else {
04936 res = (int32)src1 << src2;
04937 }
04938 break;
04939
04940 case 0x07:
04941 res = src1 & src2;
04942 break;
04943
04944 case 0x08:
04945 res = src1 | src2;
04946 break;
04947
04948 case 0x09:
04949 if (src2 == 0) {
04950 res = src1;
04951 } else {
04952 res = src1 / src2;
04953 }
04954 break;
04955
04956 case 0x0A:
04957 if (src2 == 0) {
04958 res = src1;
04959 } else {
04960 res = (int32)src1 / (int32)src2;
04961 }
04962 break;
04963
04964 case 0x0B:
04965 if (src2 == 0) {
04966 res = src1;
04967 } else {
04968 res = src1 % src2;
04969 }
04970 break;
04971
04972 case 0x0C:
04973 if (src2 == 0) {
04974 res = src1;
04975 } else {
04976 res = (int32)src1 % (int32)src2;
04977 }
04978 break;
04979
04980 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
04981 }
04982
04983 switch (target) {
04984 case 0x8E:
04985 _cur_grffile->traininfo_vehicle_pitch = res;
04986 break;
04987
04988 case 0x8F: {
04989 extern RailtypeInfo _railtypes[RAILTYPE_END];
04990 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
04991 if (_settings_game.vehicle.disable_elrails) {
04992 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
04993 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
04994 } else {
04995 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
04996 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
04997 }
04998 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
04999 break;
05000 }
05001
05002
05003 case 0x93:
05004 case 0x94:
05005 case 0x95:
05006 case 0x96:
05007 case 0x97:
05008 case 0x99:
05009 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05010 break;
05011
05012 case 0x9E:
05013 _misc_grf_features = res;
05014
05015
05016 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
05017
05018
05019 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
05020 break;
05021
05022 case 0x9F:
05023 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05024 break;
05025
05026 default:
05027 if (target < 0x80) {
05028 _cur_grffile->param[target] = res;
05029
05030 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
05031 } else {
05032 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
05033 }
05034 break;
05035 }
05036 }
05037
05038
05039 static void SafeGRFInhibit(ByteReader *buf)
05040 {
05041
05042
05043
05044
05045
05046 uint8 num = buf->ReadByte();
05047
05048 for (uint i = 0; i < num; i++) {
05049 uint32 grfid = buf->ReadDWord();
05050
05051
05052 if (grfid != _cur_grfconfig->grfid) {
05053 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05054
05055
05056 _skip_sprites = -1;
05057
05058 return;
05059 }
05060 }
05061 }
05062
05063
05064 static void GRFInhibit(ByteReader *buf)
05065 {
05066
05067
05068
05069
05070
05071 uint8 num = buf->ReadByte();
05072
05073 for (uint i = 0; i < num; i++) {
05074 uint32 grfid = buf->ReadDWord();
05075 GRFConfig *file = GetGRFConfig(grfid);
05076
05077
05078 if (file != NULL && file != _cur_grfconfig) {
05079 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
05080 file->status = GCS_DISABLED;
05081 }
05082 }
05083 }
05084
05085
05086 static void FeatureTownName(ByteReader *buf)
05087 {
05088
05089
05090
05091
05092
05093
05094
05095 uint32 grfid = _cur_grffile->grfid;
05096
05097 GRFTownName *townname = AddGRFTownName(grfid);
05098
05099 byte id = buf->ReadByte();
05100 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
05101
05102 if (HasBit(id, 7)) {
05103
05104 ClrBit(id, 7);
05105 bool new_scheme = _cur_grffile->grf_version >= 7;
05106
05107 byte lang = buf->ReadByte();
05108
05109 byte nb_gen = townname->nb_gen;
05110 do {
05111 ClrBit(lang, 7);
05112
05113 const char *name = buf->ReadString();
05114
05115 char *lang_name = TranslateTTDPatchCodes(grfid, name);
05116 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
05117 free(lang_name);
05118
05119 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
05120
05121 lang = buf->ReadByte();
05122 } while (lang != 0);
05123 townname->id[nb_gen] = id;
05124 townname->nb_gen++;
05125 }
05126
05127 byte nb = buf->ReadByte();
05128 grfmsg(6, "FeatureTownName: %u parts", nb);
05129
05130 townname->nbparts[id] = nb;
05131 townname->partlist[id] = CallocT<NamePartList>(nb);
05132
05133 for (int i = 0; i < nb; i++) {
05134 byte nbtext = buf->ReadByte();
05135 townname->partlist[id][i].bitstart = buf->ReadByte();
05136 townname->partlist[id][i].bitcount = buf->ReadByte();
05137 townname->partlist[id][i].maxprob = 0;
05138 townname->partlist[id][i].partcount = nbtext;
05139 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
05140 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);
05141
05142 for (int j = 0; j < nbtext; j++) {
05143 byte prob = buf->ReadByte();
05144
05145 if (HasBit(prob, 7)) {
05146 byte ref_id = buf->ReadByte();
05147
05148 if (townname->nbparts[ref_id] == 0) {
05149 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
05150 DelGRFTownName(grfid);
05151 _cur_grfconfig->status = GCS_DISABLED;
05152 ClearTemporaryNewGRFData(_cur_grffile);
05153 _skip_sprites = -1;
05154 return;
05155 }
05156
05157 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
05158 townname->partlist[id][i].parts[j].data.id = ref_id;
05159 } else {
05160 const char *text = buf->ReadString();
05161 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, text);
05162 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
05163 }
05164 townname->partlist[id][i].parts[j].prob = prob;
05165 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
05166 }
05167 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
05168 }
05169 }
05170
05171
05172 static void DefineGotoLabel(ByteReader *buf)
05173 {
05174
05175
05176
05177
05178
05179 byte nfo_label = buf->ReadByte();
05180
05181 GRFLabel *label = MallocT<GRFLabel>(1);
05182 label->label = nfo_label;
05183 label->nfo_line = _nfo_line;
05184 label->pos = FioGetPos();
05185 label->next = NULL;
05186
05187
05188 if (_cur_grffile->label == NULL) {
05189 _cur_grffile->label = label;
05190 } else {
05191
05192 GRFLabel *l;
05193 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
05194 l->next = label;
05195 }
05196
05197 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
05198 }
05199
05200
05201 static void GRFSound(ByteReader *buf)
05202 {
05203
05204
05205
05206
05207 uint16 num = buf->ReadWord();
05208
05209 _grf_data_blocks = num;
05210 _grf_data_type = GDT_SOUND;
05211
05212 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
05213 }
05214
05215
05216 static void SkipAct11(ByteReader *buf)
05217 {
05218
05219
05220
05221
05222 _skip_sprites = buf->ReadWord();
05223
05224 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
05225 }
05226
05227 static void ImportGRFSound(ByteReader *buf)
05228 {
05229 const GRFFile *file;
05230 SoundEntry *sound = AllocateSound();
05231 uint32 grfid = buf->ReadDWord();
05232 SoundID sound_id = buf->ReadWord();
05233
05234 file = GetFileByGRFID(grfid);
05235 if (file == NULL || file->sound_offset == 0) {
05236 grfmsg(1, "ImportGRFSound: Source file not available");
05237 return;
05238 }
05239
05240 if (file->sound_offset + sound_id >= GetNumSounds()) {
05241 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
05242 return;
05243 }
05244
05245 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
05246
05247 *sound = *GetSound(file->sound_offset + sound_id);
05248
05249
05250 sound->volume = 128;
05251 sound->priority = 0;
05252 }
05253
05254
05255 static void GRFImportBlock(ByteReader *buf)
05256 {
05257 if (_grf_data_blocks == 0) {
05258 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
05259 return;
05260 }
05261
05262 _grf_data_blocks--;
05263
05264
05265
05266 if (buf->ReadByte() != _grf_data_type) {
05267 grfmsg(1, "GRFImportBlock: Import type mismatch");
05268 }
05269
05270 switch (_grf_data_type) {
05271 case GDT_SOUND: ImportGRFSound(buf); break;
05272 default: NOT_REACHED();
05273 }
05274 }
05275
05276 static void LoadGRFSound(ByteReader *buf)
05277 {
05278
05279
05280 SoundEntry *sound = AllocateSound();
05281
05282 if (buf->ReadDWord() != BSWAP32('RIFF')) {
05283 grfmsg(1, "LoadGRFSound: Missing RIFF header");
05284 return;
05285 }
05286
05287 uint32 total_size = buf->ReadDWord();
05288 if (total_size > buf->Remaining()) {
05289 grfmsg(1, "LoadGRFSound: RIFF was truncated");
05290 return;
05291 }
05292
05293 if (buf->ReadDWord() != BSWAP32('WAVE')) {
05294 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
05295 return;
05296 }
05297
05298 while (total_size >= 8) {
05299 uint32 tag = buf->ReadDWord();
05300 uint32 size = buf->ReadDWord();
05301 total_size -= 8;
05302 if (total_size < size) {
05303 grfmsg(1, "LoadGRFSound: Invalid RIFF");
05304 return;
05305 }
05306 total_size -= size;
05307
05308 switch (tag) {
05309 case ' tmf':
05310
05311 if (size < 16 || buf->ReadWord() != 1) {
05312 grfmsg(1, "LoadGRFSound: Invalid audio format");
05313 return;
05314 }
05315 sound->channels = buf->ReadWord();
05316 sound->rate = buf->ReadDWord();
05317 buf->ReadDWord();
05318 buf->ReadWord();
05319 sound->bits_per_sample = buf->ReadWord();
05320
05321
05322 size -= 16;
05323 break;
05324
05325 case 'atad':
05326 sound->file_size = size;
05327 sound->file_offset = FioGetPos() - buf->Remaining();
05328 sound->file_slot = _file_index;
05329
05330
05331 sound->volume = 0x80;
05332 sound->priority = 0;
05333
05334 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
05335 return;
05336
05337 default:
05338
05339 break;
05340 }
05341
05342
05343 for (; size > 0; size--) buf->ReadByte();
05344 }
05345
05346 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
05347
05348
05349 MemSetT(sound, 0);
05350 }
05351
05352
05353 static void LoadFontGlyph(ByteReader *buf)
05354 {
05355
05356
05357
05358
05359
05360
05361
05362 uint8 num_def = buf->ReadByte();
05363
05364 for (uint i = 0; i < num_def; i++) {
05365 FontSize size = (FontSize)buf->ReadByte();
05366 uint8 num_char = buf->ReadByte();
05367 uint16 base_char = buf->ReadWord();
05368
05369 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
05370
05371 for (uint c = 0; c < num_char; c++) {
05372 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
05373 _nfo_line++;
05374 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
05375 }
05376 }
05377 }
05378
05379
05380 static void SkipAct12(ByteReader *buf)
05381 {
05382
05383
05384
05385
05386
05387
05388
05389 uint8 num_def = buf->ReadByte();
05390
05391 for (uint i = 0; i < num_def; i++) {
05392
05393 buf->ReadByte();
05394
05395
05396 _skip_sprites += buf->ReadByte();
05397
05398
05399 buf->ReadWord();
05400 }
05401
05402 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
05403 }
05404
05405
05406 static void TranslateGRFStrings(ByteReader *buf)
05407 {
05408
05409
05410
05411
05412
05413
05414
05415 uint32 grfid = buf->ReadDWord();
05416 const GRFConfig *c = GetGRFConfig(grfid);
05417 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
05418 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
05419 return;
05420 }
05421
05422 if (c->status == GCS_INITIALISED) {
05423
05424
05425 delete _cur_grfconfig->error;
05426 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_LOAD_AFTER);
05427
05428 char tmp[256];
05429 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
05430 _cur_grfconfig->error->data = strdup(tmp);
05431
05432 _cur_grfconfig->status = GCS_DISABLED;
05433 ClearTemporaryNewGRFData(_cur_grffile);
05434 _skip_sprites = -1;
05435 return;
05436 }
05437
05438 byte num_strings = buf->ReadByte();
05439 uint16 first_id = buf->ReadWord();
05440
05441 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
05442 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
05443 return;
05444 }
05445
05446 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
05447 const char *string = buf->ReadString();
05448
05449 if (StrEmpty(string)) {
05450 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
05451 continue;
05452 }
05453
05454
05455
05456
05457
05458
05459 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
05460 }
05461 }
05462
05463
05464 static void GRFDataBlock(ByteReader *buf)
05465 {
05466
05467
05468 if (_grf_data_blocks == 0) {
05469 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
05470 return;
05471 }
05472
05473 uint8 name_len = buf->ReadByte();
05474 const char *name = reinterpret_cast<const char *>(buf->Data());
05475 buf->Skip(name_len);
05476
05477
05478 if (buf->ReadByte() != 0) {
05479 grfmsg(2, "GRFDataBlock: Name not properly terminated");
05480 return;
05481 }
05482
05483 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
05484
05485 _grf_data_blocks--;
05486
05487 switch (_grf_data_type) {
05488 case GDT_SOUND: LoadGRFSound(buf); break;
05489 default: NOT_REACHED();
05490 }
05491 }
05492
05493
05494
05495 static void GRFUnsafe(ByteReader *buf)
05496 {
05497 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05498
05499
05500 _skip_sprites = -1;
05501 }
05502
05503
05504 static void InitializeGRFSpecial()
05505 {
05506 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
05507 | (1 << 0x0D)
05508 | (1 << 0x0E)
05509 | ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)
05510 | (0 << 0x10)
05511 | (1 << 0x12)
05512 | (1 << 0x13)
05513 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
05514 | (1 << 0x1B)
05515 | (1 << 0x1D)
05516 | (1 << 0x1E);
05517
05518 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
05519 | ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)
05520 | (1 << 0x09)
05521 | (0 << 0x0B)
05522 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
05523 | (1 << 0x12)
05524 | (1 << 0x13)
05525 | (1 << 0x14)
05526 | (1 << 0x16)
05527 | (1 << 0x17)
05528 | (1 << 0x18)
05529 | (1 << 0x19)
05530 | (1 << 0x1A)
05531 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
05532 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
05533
05534 _ttdpatch_flags[2] = (1 << 0x01)
05535 | (1 << 0x03)
05536 | (0 << 0x0B)
05537 | (0 << 0x0C)
05538 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
05539 | (1 << 0x0E)
05540 | (1 << 0x0F)
05541 | (0 << 0x10)
05542 | (0 << 0x11)
05543 | (1 << 0x12)
05544 | (1 << 0x13)
05545 | (1 << 0x14)
05546 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
05547 | (1 << 0x16)
05548 | (1 << 0x17)
05549 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
05550 | (1 << 0x19)
05551 | (1 << 0x1A)
05552 | (1 << 0x1B)
05553 | (1 << 0x1C)
05554 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
05555 | (1 << 0x1E)
05556 | (0 << 0x1F);
05557
05558 _ttdpatch_flags[3] = (0 << 0x00)
05559 | (1 << 0x01)
05560 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
05561 | (1 << 0x03)
05562 | (0 << 0x04)
05563 | (1 << 0x05)
05564 | (1 << 0x06)
05565 | (1 << 0x07)
05566 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
05567 | (0 << 0x09)
05568 | (0 << 0x0A)
05569 | (1 << 0x0B)
05570 | (1 << 0x0C)
05571 | (1 << 0x0D)
05572 | ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)
05573 | (1 << 0x0F)
05574 | (1 << 0x10)
05575 | (1 << 0x11)
05576 | (1 << 0x12)
05577 | (0 << 0x13)
05578 | (1 << 0x14)
05579 | (0 << 0x15)
05580 | (1 << 0x16)
05581 | (1 << 0x17)
05582 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
05583 | (1 << 0x1E)
05584 | (1 << 0x1F);
05585 }
05586
05587 static void ResetCustomStations()
05588 {
05589 const GRFFile * const *end = _grf_files.End();
05590 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05591 StationSpec **&stations = (*file)->stations;
05592 if (stations == NULL) continue;
05593 for (uint i = 0; i < MAX_STATIONS; i++) {
05594 if (stations[i] == NULL) continue;
05595 StationSpec *statspec = stations[i];
05596
05597
05598 if (!statspec->copied_renderdata) {
05599 for (uint t = 0; t < statspec->tiles; t++) {
05600 free((void*)statspec->renderdata[t].seq);
05601 }
05602 free(statspec->renderdata);
05603 }
05604
05605
05606 if (!statspec->copied_layouts) {
05607 for (uint l = 0; l < statspec->lengths; l++) {
05608 for (uint p = 0; p < statspec->platforms[l]; p++) {
05609 free(statspec->layouts[l][p]);
05610 }
05611 free(statspec->layouts[l]);
05612 }
05613 free(statspec->layouts);
05614 free(statspec->platforms);
05615 }
05616
05617
05618 free(statspec);
05619 }
05620
05621
05622 free(stations);
05623 stations = NULL;
05624 }
05625 }
05626
05627 static void ResetCustomHouses()
05628 {
05629 const GRFFile * const *end = _grf_files.End();
05630 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05631 HouseSpec **&housespec = (*file)->housespec;
05632 if (housespec == NULL) continue;
05633 for (uint i = 0; i < HOUSE_MAX; i++) {
05634 free(housespec[i]);
05635 }
05636
05637 free(housespec);
05638 housespec = NULL;
05639 }
05640 }
05641
05642 static void ResetCustomIndustries()
05643 {
05644 const GRFFile * const *end = _grf_files.End();
05645 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05646 IndustrySpec **&industryspec = (*file)->industryspec;
05647 IndustryTileSpec **&indtspec = (*file)->indtspec;
05648
05649
05650
05651 if (industryspec != NULL) {
05652 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
05653 IndustrySpec *ind = industryspec[i];
05654 if (ind == NULL) continue;
05655
05656
05657 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
05658 free((void*)ind->random_sounds);
05659 }
05660
05661
05662 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
05663 for (int j = 0; j < ind->num_table; j++) {
05664
05665 free((void*)ind->table[j]);
05666 }
05667
05668 free((void*)ind->table);
05669 ind->table = NULL;
05670 }
05671
05672 free(ind);
05673 }
05674
05675 free(industryspec);
05676 industryspec = NULL;
05677 }
05678
05679 if (indtspec == NULL) continue;
05680 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
05681 free(indtspec[i]);
05682 }
05683
05684 free(indtspec);
05685 indtspec = NULL;
05686 }
05687 }
05688
05689 static void ResetNewGRF()
05690 {
05691 const GRFFile * const *end = _grf_files.End();
05692 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05693 GRFFile *f = *file;
05694 free(f->filename);
05695 free(f->cargo_list);
05696 free(f->railtype_list);
05697 free(f);
05698 }
05699
05700 _grf_files.Clear();
05701 _cur_grffile = NULL;
05702 }
05703
05704 static void ResetNewGRFErrors()
05705 {
05706 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
05707 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
05708 delete c->error;
05709 c->error = NULL;
05710 }
05711 }
05712 }
05713
05718 static void ResetNewGRFData()
05719 {
05720 CleanUpStrings();
05721 CleanUpGRFTownNames();
05722
05723
05724 SetupEngines();
05725
05726
05727 ResetBridges();
05728
05729
05730 ResetRailTypes();
05731
05732
05733 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
05734
05735
05736 memset(&_grm_engines, 0, sizeof(_grm_engines));
05737 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
05738
05739
05740 ResetGenericCallbacks();
05741
05742
05743 ResetPriceBaseMultipliers();
05744
05745
05746 ResetCurrencies();
05747
05748
05749 ResetCustomHouses();
05750 ResetHouses();
05751
05752
05753 ResetCustomIndustries();
05754 ResetIndustries();
05755
05756
05757 ResetStationClasses();
05758 ResetCustomStations();
05759
05760
05761 memset(_water_feature, 0, sizeof(_water_feature));
05762
05763
05764 ClearSnowLine();
05765
05766
05767 ResetNewGRF();
05768
05769
05770 ResetNewGRFErrors();
05771
05772
05773 SetupCargoForClimate(_settings_game.game_creation.landscape);
05774
05775
05776 _misc_grf_features = 0;
05777
05778 _loaded_newgrf_features.has_2CC = false;
05779 _loaded_newgrf_features.has_newhouses = false;
05780 _loaded_newgrf_features.has_newindustries = false;
05781 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
05782
05783
05784 _grf_id_overrides.clear();
05785
05786 InitializeSoundPool();
05787 _spritegroup_pool.CleanPool();
05788 }
05789
05790 static void BuildCargoTranslationMap()
05791 {
05792 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
05793
05794 for (CargoID c = 0; c < NUM_CARGO; c++) {
05795 const CargoSpec *cs = CargoSpec::Get(c);
05796 if (!cs->IsValid()) continue;
05797
05798 if (_cur_grffile->cargo_max == 0) {
05799
05800 _cur_grffile->cargo_map[c] = cs->bitnum;
05801 } else {
05802
05803 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
05804 if (cs->label == _cur_grffile->cargo_list[i]) {
05805 _cur_grffile->cargo_map[c] = i;
05806 break;
05807 }
05808 }
05809 }
05810 }
05811 }
05812
05813 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
05814 {
05815 GRFFile *newfile = GetFileByFilename(config->filename);
05816 if (newfile != NULL) {
05817
05818 newfile->sprite_offset = sprite_offset;
05819 _cur_grffile = newfile;
05820 return;
05821 }
05822
05823 newfile = CallocT<GRFFile>(1);
05824
05825 if (newfile == NULL) error ("Out of memory");
05826
05827 newfile->filename = strdup(config->filename);
05828 newfile->sprite_offset = sprite_offset;
05829
05830
05831 newfile->traininfo_vehicle_pitch = 0;
05832 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
05833
05834
05835 for (Price i = PR_BEGIN; i < PR_END; i++) {
05836 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
05837 }
05838
05839
05840 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
05841 newfile->railtype_map[0] = RAILTYPE_RAIL;
05842 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
05843 newfile->railtype_map[2] = RAILTYPE_MONO;
05844 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
05845
05846
05847
05848 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
05849 memset(newfile->param, 0, sizeof(newfile->param));
05850
05851 assert(config->num_params <= lengthof(config->param));
05852 newfile->param_end = config->num_params;
05853 if (newfile->param_end > 0) {
05854 MemCpyT(newfile->param, config->param, newfile->param_end);
05855 }
05856
05857 *_grf_files.Append() = _cur_grffile = newfile;
05858 }
05859
05860
05863 static const CargoLabel _default_refitmasks_rail[] = {
05864 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
05865 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
05866 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05867 'PLST', 'FZDR',
05868 0 };
05869
05870 static const CargoLabel _default_refitmasks_road[] = {
05871 0 };
05872
05873 static const CargoLabel _default_refitmasks_ships[] = {
05874 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
05875 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
05876 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05877 'PLST', 'FZDR',
05878 0 };
05879
05880 static const CargoLabel _default_refitmasks_aircraft[] = {
05881 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
05882 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
05883 0 };
05884
05885 static const CargoLabel * const _default_refitmasks[] = {
05886 _default_refitmasks_rail,
05887 _default_refitmasks_road,
05888 _default_refitmasks_ships,
05889 _default_refitmasks_aircraft,
05890 };
05891
05892
05896 static void CalculateRefitMasks()
05897 {
05898 Engine *e;
05899
05900 FOR_ALL_ENGINES(e) {
05901 EngineID engine = e->index;
05902 EngineInfo *ei = &e->info;
05903 uint32 mask = 0;
05904 uint32 not_mask = 0;
05905 uint32 xor_mask = 0;
05906
05907
05908 if (_gted[engine].refitmask_valid) {
05909 if (ei->refit_mask != 0) {
05910 const GRFFile *file = e->grffile;
05911 if (file != NULL && file->cargo_max != 0) {
05912
05913 uint num_cargo = min(32, file->cargo_max);
05914 for (uint i = 0; i < num_cargo; i++) {
05915 if (!HasBit(ei->refit_mask, i)) continue;
05916
05917 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
05918 if (c == CT_INVALID) continue;
05919
05920 SetBit(xor_mask, c);
05921 }
05922 } else {
05923
05924 const CargoSpec *cs;
05925 FOR_ALL_CARGOSPECS(cs) {
05926 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
05927 }
05928 }
05929 }
05930
05931 if (_gted[engine].cargo_allowed != 0) {
05932
05933 const CargoSpec *cs;
05934 FOR_ALL_CARGOSPECS(cs) {
05935 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
05936 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
05937 }
05938 }
05939 } else {
05940
05941 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
05942 const CargoLabel *cl = _default_refitmasks[e->type];
05943 for (uint i = 0;; i++) {
05944 if (cl[i] == 0) break;
05945
05946 CargoID cargo = GetCargoIDByLabel(cl[i]);
05947 if (cargo == CT_INVALID) continue;
05948
05949 SetBit(xor_mask, cargo);
05950 }
05951 }
05952 }
05953
05954 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
05955
05956
05957
05958 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
05959 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
05960
05961
05962 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
05963 }
05964 }
05965
05970 static void FinaliseHouseArray()
05971 {
05972
05973
05974
05975
05976
05977
05978
05979
05980
05981 Year min_year = MAX_YEAR;
05982
05983 const GRFFile * const *end = _grf_files.End();
05984 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05985 HouseSpec **&housespec = (*file)->housespec;
05986 if (housespec == NULL) continue;
05987
05988 for (int i = 0; i < HOUSE_MAX; i++) {
05989 HouseSpec *hs = housespec[i];
05990
05991 if (hs == NULL) continue;
05992
05993 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
05994 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
05995 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
05996
05997 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
05998 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
05999 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
06000 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
06001 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
06002 hs->enabled = false;
06003 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", (*file)->filename, hs->local_id);
06004 continue;
06005 }
06006
06007
06008
06009
06010 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
06011 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
06012 hs->enabled = false;
06013 DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", (*file)->filename, hs->local_id);
06014 continue;
06015 }
06016
06017 _house_mngr.SetEntitySpec(hs);
06018 if (hs->min_year < min_year) min_year = hs->min_year;
06019 }
06020 }
06021
06022 if (min_year != 0) {
06023 for (int i = 0; i < HOUSE_MAX; i++) {
06024 HouseSpec *hs = HouseSpec::Get(i);
06025
06026 if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
06027 }
06028 }
06029 }
06030
06034 static void FinaliseIndustriesArray()
06035 {
06036 const GRFFile * const *end = _grf_files.End();
06037 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06038 IndustrySpec **&industryspec = (*file)->industryspec;
06039 IndustryTileSpec **&indtspec = (*file)->indtspec;
06040 if (industryspec != NULL) {
06041 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
06042 IndustrySpec *indsp = industryspec[i];
06043
06044 if (indsp != NULL && indsp->enabled) {
06045 StringID strid;
06046
06047
06048
06049 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
06050 if (strid != STR_UNDEFINED) indsp->name = strid;
06051
06052 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
06053 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
06054
06055 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
06056 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
06057
06058 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
06059 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
06060
06061 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
06062 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
06063
06064 if (indsp->station_name != STR_NULL) {
06065
06066
06067 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
06068 if (strid != STR_UNDEFINED) indsp->station_name = strid;
06069 }
06070
06071 _industry_mngr.SetEntitySpec(indsp);
06072 _loaded_newgrf_features.has_newindustries = true;
06073 }
06074 }
06075 }
06076
06077 if (indtspec != NULL) {
06078 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
06079 IndustryTileSpec *indtsp = indtspec[i];
06080 if (indtsp != NULL) {
06081 _industile_mngr.SetEntitySpec(indtsp);
06082 }
06083 }
06084 }
06085 }
06086
06087 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
06088 IndustrySpec *indsp = &_industry_specs[j];
06089 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
06090 for (uint i = 0; i < 3; i++) {
06091 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
06092 }
06093 }
06094 }
06095 }
06096
06097
06098
06099
06100
06101
06102
06103 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
06104 {
06105
06106
06107
06108
06109
06110
06111
06112
06113
06114
06115
06116
06117 static const SpecialSpriteHandler handlers[][GLS_END] = {
06118 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
06119 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
06120 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
06121 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
06122 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
06123 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
06124 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
06125 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
06126 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
06127 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
06128 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
06129 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
06130 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
06131 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
06132 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
06133 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
06134 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
06135 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
06136 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
06137 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
06138 };
06139
06140 GRFLocation location(_cur_grfconfig->grfid, _nfo_line);
06141
06142 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
06143 if (it == _grf_line_to_action6_sprite_override.end()) {
06144
06145
06146 FioReadBlock(buf, num);
06147 } else {
06148
06149 buf = _grf_line_to_action6_sprite_override[location];
06150 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
06151
06152
06153 FioSeekTo(num, SEEK_CUR);
06154 }
06155
06156 ByteReader br(buf, buf + num);
06157 ByteReader *bufp = &br;
06158
06159 try {
06160 byte action = bufp->ReadByte();
06161
06162 if (action == 0xFF) {
06163 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
06164 GRFDataBlock(bufp);
06165 } else if (action == 0xFE) {
06166 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
06167 GRFImportBlock(bufp);
06168 } else if (action >= lengthof(handlers)) {
06169 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
06170 } else if (handlers[action][stage] == NULL) {
06171 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
06172 } else {
06173 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
06174 handlers[action][stage](bufp);
06175 }
06176 } catch (...) {
06177 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
06178
06179 _skip_sprites = -1;
06180 _cur_grfconfig->status = GCS_DISABLED;
06181 delete _cur_grfconfig->error;
06182 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_READ_BOUNDS);
06183 }
06184 }
06185
06186
06187 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
06188 {
06189 const char *filename = config->filename;
06190 uint16 num;
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
06202 _cur_grffile = GetFileByFilename(filename);
06203 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
06204 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
06205 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
06206 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
06207 }
06208
06209 if (file_index > LAST_GRF_SLOT) {
06210 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
06211 config->status = GCS_DISABLED;
06212 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
06213 return;
06214 }
06215
06216 FioOpenFile(file_index, filename);
06217 _file_index = file_index;
06218 _palette_remap_grf[_file_index] = (config->windows_paletted != (_use_palette == PAL_WINDOWS));
06219
06220 _cur_grfconfig = config;
06221
06222 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
06223
06224
06225
06226
06227 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
06228 FioReadDword();
06229 } else {
06230 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
06231 return;
06232 }
06233
06234 _skip_sprites = 0;
06235 _nfo_line = 0;
06236
06237 ReusableBuffer<byte> buf;
06238
06239 while ((num = FioReadWord()) != 0) {
06240 byte type = FioReadByte();
06241 _nfo_line++;
06242
06243 if (type == 0xFF) {
06244 if (_skip_sprites == 0) {
06245 DecodeSpecialSprite(buf.Allocate(num), num, stage);
06246
06247
06248 if (_skip_sprites == -1) break;
06249
06250 continue;
06251 } else {
06252 FioSkipBytes(num);
06253 }
06254 } else {
06255 if (_skip_sprites == 0) {
06256 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
06257 config->status = GCS_DISABLED;
06258 delete config->error;
06259 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
06260 break;
06261 }
06262
06263 FioSkipBytes(7);
06264 SkipSpriteData(type, num - 8);
06265 }
06266
06267 if (_skip_sprites > 0) _skip_sprites--;
06268 }
06269 }
06270
06278 static void ActivateOldShore()
06279 {
06280
06281
06282 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06283
06284 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
06285 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
06286 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
06287 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
06288 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
06289 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
06290 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
06291 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
06292 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
06293 }
06294
06295 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
06296 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
06297 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
06298 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
06299 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
06300 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
06301 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
06302 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
06303 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
06304
06305
06306
06307 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
06308 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
06309 }
06310 }
06311
06315 static void FinalisePriceBaseMultipliers()
06316 {
06317 extern const PriceBaseSpec _price_base_specs[];
06318 static const uint32 override_features = (1 << GSF_TRAIN) | (1 << GSF_ROAD) | (1 << GSF_SHIP) | (1 << GSF_AIRCRAFT);
06319
06320
06321 int num_grfs = _grf_files.Length();
06322 int *grf_overrides = AllocaM(int, num_grfs);
06323 for (int i = 0; i < num_grfs; i++) {
06324 grf_overrides[i] = -1;
06325
06326 GRFFile *source = _grf_files[i];
06327 uint32 override = _grf_id_overrides[source->grfid];
06328 if (override == 0) continue;
06329
06330 GRFFile *dest = GetFileByGRFID(override);
06331 if (dest == NULL) continue;
06332
06333 grf_overrides[i] = _grf_files.FindIndex(dest);
06334 assert(grf_overrides[i] >= 0);
06335 }
06336
06337
06338 for (int i = 0; i < num_grfs; i++) {
06339 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
06340 GRFFile *source = _grf_files[i];
06341 GRFFile *dest = _grf_files[grf_overrides[i]];
06342
06343 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06344 source->grf_features |= features;
06345 dest->grf_features |= features;
06346
06347 for (Price p = PR_BEGIN; p < PR_END; p++) {
06348
06349 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
06350 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
06351 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06352 }
06353 }
06354
06355
06356 for (int i = num_grfs - 1; i >= 0; i--) {
06357 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
06358 GRFFile *source = _grf_files[i];
06359 GRFFile *dest = _grf_files[grf_overrides[i]];
06360
06361 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06362 source->grf_features |= features;
06363 dest->grf_features |= features;
06364
06365 for (Price p = PR_BEGIN; p < PR_END; p++) {
06366
06367 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
06368 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
06369 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06370 }
06371 }
06372
06373
06374 for (int i = 0; i < num_grfs; i++) {
06375 if (grf_overrides[i] < 0) continue;
06376 GRFFile *source = _grf_files[i];
06377 GRFFile *dest = _grf_files[grf_overrides[i]];
06378
06379 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06380 source->grf_features |= features;
06381 dest->grf_features |= features;
06382
06383 for (Price p = PR_BEGIN; p < PR_END; p++) {
06384 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
06385 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
06386 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
06387 }
06388 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
06389 }
06390 }
06391
06392
06393 const GRFFile * const *end = _grf_files.End();
06394 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06395 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06396 for (Price p = PR_BEGIN; p < PR_END; p++) {
06397 Price fallback_price = _price_base_specs[p].fallback_price;
06398 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06399
06400
06401 price_base_multipliers[p] = price_base_multipliers[fallback_price];
06402 }
06403 }
06404 }
06405
06406
06407 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06408 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06409 for (Price p = PR_BEGIN; p < PR_END; p++) {
06410 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06411
06412 price_base_multipliers[p] = 0;
06413 } else {
06414 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
06415
06416
06417 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
06418 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
06419 price_base_multipliers[p] = 0;
06420 } else {
06421 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
06422 }
06423 }
06424 }
06425 }
06426 }
06427
06428 void InitDepotWindowBlockSizes();
06429
06430 extern void InitGRFTownGeneratorNames();
06431
06432 static void AfterLoadGRFs()
06433 {
06434 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
06435 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
06436 }
06437 _string_to_grf_mapping.clear();
06438
06439
06440 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
06441 free((*it).second);
06442 }
06443 _grf_line_to_action6_sprite_override.clear();
06444
06445
06446 CalculateRefitMasks();
06447
06448
06449 InitDepotWindowBlockSizes();
06450
06451
06452 FinaliseHouseArray();
06453
06454
06455 FinaliseIndustriesArray();
06456
06457
06458 BuildIndustriesLegend();
06459
06460
06461 InitGRFTownGeneratorNames();
06462
06463
06464 CommitVehicleListOrderChanges();
06465
06466
06467 ActivateOldShore();
06468
06469
06470 InitRailTypes();
06471
06472 Engine *e;
06473 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
06474 if (_gted[e->index].rv_max_speed != 0) {
06475
06476 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
06477 }
06478 }
06479
06480 SetYearEngineAgingStops();
06481
06482 FinalisePriceBaseMultipliers();
06483
06484
06485 free(_gted);
06486 _grm_sprites.clear();
06487 }
06488
06489 void LoadNewGRF(uint load_index, uint file_index)
06490 {
06491
06492
06493
06494
06495 Date date = _date;
06496 Year year = _cur_year;
06497 DateFract date_fract = _date_fract;
06498 uint16 tick_counter = _tick_counter;
06499 byte display_opt = _display_opt;
06500
06501 if (_networking) {
06502 _cur_year = _settings_game.game_creation.starting_year;
06503 _date = ConvertYMDToDate(_cur_year, 0, 1);
06504 _date_fract = 0;
06505 _tick_counter = 0;
06506 _display_opt = 0;
06507 }
06508
06509 InitializeGRFSpecial();
06510
06511 ResetNewGRFData();
06512
06513
06514
06515
06516
06517
06518
06519
06520 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06521 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
06522 }
06523
06524 _cur_spriteid = load_index;
06525
06526
06527
06528
06529 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
06530
06531
06532 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06533 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
06534 }
06535
06536 uint slot = file_index;
06537
06538 _cur_stage = stage;
06539 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06540 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
06541 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
06542
06543 if (!FioCheckFileExists(c->filename)) {
06544 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
06545 c->status = GCS_NOT_FOUND;
06546 continue;
06547 }
06548
06549 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
06550 LoadNewGRFFile(c, slot++, stage);
06551 if (stage == GLS_RESERVE) {
06552 SetBit(c->flags, GCF_RESERVED);
06553 } else if (stage == GLS_ACTIVATION) {
06554 ClrBit(c->flags, GCF_RESERVED);
06555 assert(GetFileByGRFID(c->grfid) == _cur_grffile);
06556 ClearTemporaryNewGRFData(_cur_grffile);
06557 BuildCargoTranslationMap();
06558 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
06559 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
06560
06561 ClearTemporaryNewGRFData(_cur_grffile);
06562 }
06563 }
06564 }
06565
06566
06567 AfterLoadGRFs();
06568
06569
06570 _cur_year = year;
06571 _date = date;
06572 _date_fract = date_fract;
06573 _tick_counter = tick_counter;
06574 _display_opt = display_opt;
06575 }
06576
06577 bool HasGrfMiscBit(GrfMiscBit bit)
06578 {
06579 return HasBit(_misc_grf_features, bit);
06580 }