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