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