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 if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
04460
04461
04462 GRFConfig *c = GetGRFConfig(cond_val, mask);
04463
04464 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
04465 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04466 c = NULL;
04467 }
04468
04469 if (condtype != 10 && c == NULL) {
04470 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
04471 return;
04472 }
04473
04474 switch (condtype) {
04475
04476 case 0x06:
04477 result = c->status == GCS_ACTIVATED;
04478 break;
04479
04480 case 0x07:
04481 result = c->status != GCS_ACTIVATED;
04482 break;
04483
04484 case 0x08:
04485 result = c->status == GCS_INITIALISED;
04486 break;
04487
04488 case 0x09:
04489 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
04490 break;
04491
04492 case 0x0A:
04493
04494 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
04495 break;
04496
04497 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
04498 }
04499 } else {
04500
04501 switch (condtype) {
04502 case 0x00: result = !!(param_val & (1 << cond_val));
04503 break;
04504 case 0x01: result = !(param_val & (1 << cond_val));
04505 break;
04506 case 0x02: result = (param_val & mask) == cond_val;
04507 break;
04508 case 0x03: result = (param_val & mask) != cond_val;
04509 break;
04510 case 0x04: result = (param_val & mask) < cond_val;
04511 break;
04512 case 0x05: result = (param_val & mask) > cond_val;
04513 break;
04514 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
04515 break;
04516 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
04517 break;
04518 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
04519 break;
04520 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
04521 break;
04522
04523 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
04524 }
04525 }
04526
04527 if (!result) {
04528 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
04529 return;
04530 }
04531
04532 uint8 numsprites = buf->ReadByte();
04533
04534
04535
04536
04537
04538 GRFLabel *choice = NULL;
04539 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
04540 if (label->label != numsprites) continue;
04541
04542
04543 if (choice == NULL) choice = label;
04544
04545 if (label->nfo_line > _nfo_line) {
04546 choice = label;
04547 break;
04548 }
04549 }
04550
04551 if (choice != NULL) {
04552 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
04553 FioSeekTo(choice->pos, SEEK_SET);
04554 _nfo_line = choice->nfo_line;
04555 return;
04556 }
04557
04558 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
04559 _skip_sprites = numsprites;
04560 if (_skip_sprites == 0) {
04561
04562
04563
04564 _skip_sprites = -1;
04565
04566
04567 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
04568 _cur_grfconfig->status = GCS_DISABLED;
04569 ClearTemporaryNewGRFData(_cur_grffile);
04570 }
04571 }
04572 }
04573
04574
04575
04576 static void ScanInfo(ByteReader *buf)
04577 {
04578 buf->ReadByte();
04579 uint32 grfid = buf->ReadDWord();
04580
04581 _cur_grfconfig->grfid = grfid;
04582
04583
04584 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
04585
04586 const char *name = buf->ReadString();
04587 _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name);
04588
04589 if (buf->HasData()) {
04590 const char *info = buf->ReadString();
04591 _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info);
04592 }
04593
04594
04595 _skip_sprites = -1;
04596 }
04597
04598
04599 static void GRFInfo(ByteReader *buf)
04600 {
04601
04602
04603
04604
04605
04606
04607
04608 uint8 version = buf->ReadByte();
04609 uint32 grfid = buf->ReadDWord();
04610 const char *name = buf->ReadString();
04611
04612 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
04613 _cur_grfconfig->status = GCS_DISABLED;
04614 delete _cur_grfconfig->error;
04615 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
04616
04617 _skip_sprites = -1;
04618 return;
04619 }
04620
04621 _cur_grffile->grfid = grfid;
04622 _cur_grffile->grf_version = version;
04623 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
04624
04625
04626 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
04627 }
04628
04629
04630 static void SpriteReplace(ByteReader *buf)
04631 {
04632
04633
04634
04635
04636
04637
04638
04639
04640 uint8 num_sets = buf->ReadByte();
04641
04642 for (uint i = 0; i < num_sets; i++) {
04643 uint8 num_sprites = buf->ReadByte();
04644 uint16 first_sprite = buf->ReadWord();
04645
04646 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
04647 i, num_sprites, first_sprite
04648 );
04649
04650 for (uint j = 0; j < num_sprites; j++) {
04651 int load_index = first_sprite + j;
04652 _nfo_line++;
04653 LoadNextSprite(load_index, _file_index, _nfo_line);
04654
04655
04656
04657 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
04658 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
04659 }
04660 }
04661 }
04662 }
04663
04664
04665 static void SkipActA(ByteReader *buf)
04666 {
04667 uint8 num_sets = buf->ReadByte();
04668
04669 for (uint i = 0; i < num_sets; i++) {
04670
04671 _skip_sprites += buf->ReadByte();
04672
04673 buf->ReadWord();
04674 }
04675
04676 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
04677 }
04678
04679
04680 static void GRFLoadError(ByteReader *buf)
04681 {
04682
04683
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697 static const StringID msgstr[] = {
04698 STR_NEWGRF_ERROR_VERSION_NUMBER,
04699 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
04700 STR_NEWGRF_ERROR_UNSET_SWITCH,
04701 STR_NEWGRF_ERROR_INVALID_PARAMETER,
04702 STR_NEWGRF_ERROR_LOAD_BEFORE,
04703 STR_NEWGRF_ERROR_LOAD_AFTER,
04704 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
04705 };
04706
04707 static const StringID sevstr[] = {
04708 STR_NEWGRF_ERROR_MSG_INFO,
04709 STR_NEWGRF_ERROR_MSG_WARNING,
04710 STR_NEWGRF_ERROR_MSG_ERROR,
04711 STR_NEWGRF_ERROR_MSG_FATAL
04712 };
04713
04714
04715 if (_cur_grfconfig->error != NULL) return;
04716
04717 byte severity = buf->ReadByte();
04718 byte lang = buf->ReadByte();
04719 byte message_id = buf->ReadByte();
04720
04721
04722 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
04723
04724
04725
04726 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
04727 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
04728 return;
04729 }
04730 ClrBit(severity, 7);
04731
04732 if (severity >= lengthof(sevstr)) {
04733 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
04734 severity = 2;
04735 } else if (severity == 3) {
04736
04737
04738 _cur_grfconfig->status = GCS_DISABLED;
04739 ClearTemporaryNewGRFData(_cur_grffile);
04740 _skip_sprites = -1;
04741 }
04742
04743 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
04744 grfmsg(7, "GRFLoadError: Invalid message id.");
04745 return;
04746 }
04747
04748 if (buf->Remaining() <= 1) {
04749 grfmsg(7, "GRFLoadError: No message data supplied.");
04750 return;
04751 }
04752
04753 GRFError *error = new GRFError(sevstr[severity]);
04754
04755 if (message_id == 0xFF) {
04756
04757 if (buf->HasData()) {
04758 const char *message = buf->ReadString();
04759
04760 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, message);
04761 } else {
04762 grfmsg(7, "GRFLoadError: No custom message supplied.");
04763 error->custom_message = strdup("");
04764 }
04765 } else {
04766 error->message = msgstr[message_id];
04767 }
04768
04769 if (buf->HasData()) {
04770 const char *data = buf->ReadString();
04771
04772 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, data);
04773 } else {
04774 grfmsg(7, "GRFLoadError: No message data supplied.");
04775 error->data = strdup("");
04776 }
04777
04778
04779 uint i = 0;
04780 for (; i < 2 && buf->HasData(); i++) {
04781 uint param_number = buf->ReadByte();
04782 error->param_value[i] = _cur_grffile->GetParam(param_number);
04783 }
04784 error->num_params = i;
04785
04786 _cur_grfconfig->error = error;
04787 }
04788
04789
04790 static void GRFComment(ByteReader *buf)
04791 {
04792
04793
04794
04795
04796 if (!buf->HasData()) return;
04797
04798 const char *text = buf->ReadString();
04799 grfmsg(2, "GRFComment: %s", text);
04800 }
04801
04802
04803 static void SafeParamSet(ByteReader *buf)
04804 {
04805 uint8 target = buf->ReadByte();
04806
04807
04808 if (target < 0x80) return;
04809
04810
04811
04812
04813
04814
04815 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04816
04817
04818 _skip_sprites = -1;
04819 }
04820
04821
04822 static uint32 GetPatchVariable(uint8 param)
04823 {
04824 switch (param) {
04825
04826 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
04827
04828
04829 case 0x0E: return _settings_game.vehicle.freight_trains;
04830
04831
04832 case 0x0F: return 0;
04833
04834
04835
04836
04837 case 0x10:
04838 switch (_settings_game.vehicle.plane_speed) {
04839 default:
04840 case 4: return 1;
04841 case 3: return 2;
04842 case 2: return 2;
04843 case 1: return 4;
04844 }
04845
04846
04847
04848 case 0x11: return SPR_2CCMAP_BASE;
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861 case 0x13: {
04862 byte map_bits = 0;
04863 byte log_X = MapLogX() - 6;
04864 byte log_Y = MapLogY() - 6;
04865 byte max_edge = max(log_X, log_Y);
04866
04867 if (log_X == log_Y) {
04868 SetBit(map_bits, 0);
04869 } else {
04870 if (max_edge == log_Y) SetBit(map_bits, 1);
04871 }
04872
04873 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
04874 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
04875 }
04876
04877 default:
04878 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
04879 return 0;
04880 }
04881 }
04882
04883
04884 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
04885 {
04886 uint start = 0;
04887 uint size = 0;
04888
04889 if (op == 6) {
04890
04891 return grm[_cur_grffile->GetParam(target)];
04892 }
04893
04894
04895 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
04896
04897 for (uint i = start; i < num_ids; i++) {
04898 if (grm[i] == 0) {
04899 size++;
04900 } else {
04901 if (op == 2 || op == 3) break;
04902 start = i + 1;
04903 size = 0;
04904 }
04905
04906 if (size == count) break;
04907 }
04908
04909 if (size == count) {
04910
04911 if (op == 0 || op == 3) {
04912 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
04913 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
04914 }
04915 return start;
04916 }
04917
04918
04919 if (op != 4 && op != 5) {
04920
04921 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
04922 _cur_grfconfig->status = GCS_DISABLED;
04923 ClearTemporaryNewGRFData(_cur_grffile);
04924 _skip_sprites = -1;
04925 return UINT_MAX;
04926 }
04927
04928 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
04929 return UINT_MAX;
04930 }
04931
04932
04933
04934 static void ParamSet(ByteReader *buf)
04935 {
04936
04937
04938
04939
04940
04941
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958 uint8 target = buf->ReadByte();
04959 uint8 oper = buf->ReadByte();
04960 uint32 src1 = buf->ReadByte();
04961 uint32 src2 = buf->ReadByte();
04962
04963 uint32 data = 0;
04964 if (buf->Remaining() >= 4) data = buf->ReadDWord();
04965
04966
04967
04968
04969
04970
04971
04972 if (HasBit(oper, 7)) {
04973 if (target < 0x80 && target < _cur_grffile->param_end) {
04974 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
04975 return;
04976 }
04977
04978 oper = GB(oper, 0, 7);
04979 }
04980
04981 if (src2 == 0xFE) {
04982 if (GB(data, 0, 8) == 0xFF) {
04983 if (data == 0x0000FFFF) {
04984
04985 src1 = GetPatchVariable(src1);
04986 } else {
04987
04988 uint8 op = src1;
04989 uint8 feature = GB(data, 8, 8);
04990 uint16 count = GB(data, 16, 16);
04991
04992 if (_cur_stage == GLS_RESERVE) {
04993 if (feature == 0x08) {
04994
04995 if (op == 0) {
04996
04997 if (_cur_spriteid + count >= 16384) {
04998 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
04999 _cur_grfconfig->status = GCS_DISABLED;
05000 ClearTemporaryNewGRFData(_cur_grffile);
05001 _skip_sprites = -1;
05002 return;
05003 }
05004
05005
05006 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
05007 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
05008 _cur_spriteid += count;
05009 }
05010 }
05011
05012 src1 = 0;
05013 } else if (_cur_stage == GLS_ACTIVATION) {
05014 switch (feature) {
05015 case 0x00:
05016 case 0x01:
05017 case 0x02:
05018 case 0x03:
05019 if (!_settings_game.vehicle.dynamic_engines) {
05020 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
05021 if (_skip_sprites == -1) return;
05022 } else {
05023
05024 switch (op) {
05025 case 2:
05026 case 3:
05027 src1 = _cur_grffile->GetParam(target);
05028 break;
05029
05030 default:
05031 src1 = 0;
05032 break;
05033 }
05034 }
05035 break;
05036
05037 case 0x08:
05038 switch (op) {
05039 case 0:
05040
05041 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
05042 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
05043 break;
05044
05045 case 1:
05046 src1 = _cur_spriteid;
05047 break;
05048
05049 default:
05050 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
05051 return;
05052 }
05053 break;
05054
05055 case 0x0B:
05056
05057 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
05058 if (_skip_sprites == -1) return;
05059 break;
05060
05061 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
05062 }
05063 } else {
05064
05065 src1 = 0;
05066 }
05067 }
05068 } else {
05069
05070 const GRFFile *file = GetFileByGRFID(data);
05071 GRFConfig *c = GetGRFConfig(data);
05072 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05073
05074 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05075 src1 = 0;
05076 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
05077 src1 = 0;
05078 } else {
05079 src1 = file->GetParam(src1);
05080 }
05081 }
05082 } else {
05083
05084
05085
05086
05087
05088 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
05089 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
05090 }
05091
05092
05093
05094
05095
05096
05097
05098 uint32 res;
05099 switch (oper) {
05100 case 0x00:
05101 res = src1;
05102 break;
05103
05104 case 0x01:
05105 res = src1 + src2;
05106 break;
05107
05108 case 0x02:
05109 res = src1 - src2;
05110 break;
05111
05112 case 0x03:
05113 res = src1 * src2;
05114 break;
05115
05116 case 0x04:
05117 res = (int32)src1 * (int32)src2;
05118 break;
05119
05120 case 0x05:
05121 if ((int32)src2 < 0) {
05122 res = src1 >> -(int32)src2;
05123 } else {
05124 res = src1 << src2;
05125 }
05126 break;
05127
05128 case 0x06:
05129 if ((int32)src2 < 0) {
05130 res = (int32)src1 >> -(int32)src2;
05131 } else {
05132 res = (int32)src1 << src2;
05133 }
05134 break;
05135
05136 case 0x07:
05137 res = src1 & src2;
05138 break;
05139
05140 case 0x08:
05141 res = src1 | src2;
05142 break;
05143
05144 case 0x09:
05145 if (src2 == 0) {
05146 res = src1;
05147 } else {
05148 res = src1 / src2;
05149 }
05150 break;
05151
05152 case 0x0A:
05153 if (src2 == 0) {
05154 res = src1;
05155 } else {
05156 res = (int32)src1 / (int32)src2;
05157 }
05158 break;
05159
05160 case 0x0B:
05161 if (src2 == 0) {
05162 res = src1;
05163 } else {
05164 res = src1 % src2;
05165 }
05166 break;
05167
05168 case 0x0C:
05169 if (src2 == 0) {
05170 res = src1;
05171 } else {
05172 res = (int32)src1 % (int32)src2;
05173 }
05174 break;
05175
05176 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
05177 }
05178
05179 switch (target) {
05180 case 0x8E:
05181 _cur_grffile->traininfo_vehicle_pitch = res;
05182 break;
05183
05184 case 0x8F: {
05185 extern RailtypeInfo _railtypes[RAILTYPE_END];
05186 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
05187 if (_settings_game.vehicle.disable_elrails) {
05188 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
05189 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
05190 } else {
05191 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
05192 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
05193 }
05194 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
05195 break;
05196 }
05197
05198
05199 case 0x93:
05200 case 0x94:
05201 case 0x95:
05202 case 0x96:
05203 case 0x97:
05204 case 0x99:
05205 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05206 break;
05207
05208 case 0x9E:
05209 _misc_grf_features = res;
05210
05211
05212 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
05213
05214
05215 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
05216 break;
05217
05218 case 0x9F:
05219 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
05220 break;
05221
05222 default:
05223 if (target < 0x80) {
05224 _cur_grffile->param[target] = res;
05225
05226 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
05227 } else {
05228 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
05229 }
05230 break;
05231 }
05232 }
05233
05234
05235 static void SafeGRFInhibit(ByteReader *buf)
05236 {
05237
05238
05239
05240
05241
05242 uint8 num = buf->ReadByte();
05243
05244 for (uint i = 0; i < num; i++) {
05245 uint32 grfid = buf->ReadDWord();
05246
05247
05248 if (grfid != _cur_grfconfig->grfid) {
05249 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05250
05251
05252 _skip_sprites = -1;
05253
05254 return;
05255 }
05256 }
05257 }
05258
05259
05260 static void GRFInhibit(ByteReader *buf)
05261 {
05262
05263
05264
05265
05266
05267 uint8 num = buf->ReadByte();
05268
05269 for (uint i = 0; i < num; i++) {
05270 uint32 grfid = buf->ReadDWord();
05271 GRFConfig *file = GetGRFConfig(grfid);
05272
05273
05274 if (file != NULL && file != _cur_grfconfig) {
05275 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
05276 file->status = GCS_DISABLED;
05277 }
05278 }
05279 }
05280
05281
05282 static void FeatureTownName(ByteReader *buf)
05283 {
05284
05285
05286
05287
05288
05289
05290
05291 uint32 grfid = _cur_grffile->grfid;
05292
05293 GRFTownName *townname = AddGRFTownName(grfid);
05294
05295 byte id = buf->ReadByte();
05296 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
05297
05298 if (HasBit(id, 7)) {
05299
05300 ClrBit(id, 7);
05301 bool new_scheme = _cur_grffile->grf_version >= 7;
05302
05303 byte lang = buf->ReadByte();
05304
05305 byte nb_gen = townname->nb_gen;
05306 do {
05307 ClrBit(lang, 7);
05308
05309 const char *name = buf->ReadString();
05310
05311 char *lang_name = TranslateTTDPatchCodes(grfid, name);
05312 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
05313 free(lang_name);
05314
05315 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
05316
05317 lang = buf->ReadByte();
05318 } while (lang != 0);
05319 townname->id[nb_gen] = id;
05320 townname->nb_gen++;
05321 }
05322
05323 byte nb = buf->ReadByte();
05324 grfmsg(6, "FeatureTownName: %u parts", nb);
05325
05326 townname->nbparts[id] = nb;
05327 townname->partlist[id] = CallocT<NamePartList>(nb);
05328
05329 for (int i = 0; i < nb; i++) {
05330 byte nbtext = buf->ReadByte();
05331 townname->partlist[id][i].bitstart = buf->ReadByte();
05332 townname->partlist[id][i].bitcount = buf->ReadByte();
05333 townname->partlist[id][i].maxprob = 0;
05334 townname->partlist[id][i].partcount = nbtext;
05335 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
05336 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);
05337
05338 for (int j = 0; j < nbtext; j++) {
05339 byte prob = buf->ReadByte();
05340
05341 if (HasBit(prob, 7)) {
05342 byte ref_id = buf->ReadByte();
05343
05344 if (townname->nbparts[ref_id] == 0) {
05345 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
05346 DelGRFTownName(grfid);
05347 _cur_grfconfig->status = GCS_DISABLED;
05348 ClearTemporaryNewGRFData(_cur_grffile);
05349 _skip_sprites = -1;
05350 return;
05351 }
05352
05353 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
05354 townname->partlist[id][i].parts[j].data.id = ref_id;
05355 } else {
05356 const char *text = buf->ReadString();
05357 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, text);
05358 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
05359 }
05360 townname->partlist[id][i].parts[j].prob = prob;
05361 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
05362 }
05363 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
05364 }
05365 }
05366
05367
05368 static void DefineGotoLabel(ByteReader *buf)
05369 {
05370
05371
05372
05373
05374
05375 byte nfo_label = buf->ReadByte();
05376
05377 GRFLabel *label = MallocT<GRFLabel>(1);
05378 label->label = nfo_label;
05379 label->nfo_line = _nfo_line;
05380 label->pos = FioGetPos();
05381 label->next = NULL;
05382
05383
05384 if (_cur_grffile->label == NULL) {
05385 _cur_grffile->label = label;
05386 } else {
05387
05388 GRFLabel *l;
05389 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
05390 l->next = label;
05391 }
05392
05393 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
05394 }
05395
05396
05397 static void GRFSound(ByteReader *buf)
05398 {
05399
05400
05401
05402
05403 uint16 num = buf->ReadWord();
05404
05405 _grf_data_blocks = num;
05406 _grf_data_type = GDT_SOUND;
05407
05408 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
05409 }
05410
05411
05412 static void SkipAct11(ByteReader *buf)
05413 {
05414
05415
05416
05417
05418 _skip_sprites = buf->ReadWord();
05419
05420 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
05421 }
05422
05423 static void ImportGRFSound(ByteReader *buf)
05424 {
05425 const GRFFile *file;
05426 SoundEntry *sound = AllocateSound();
05427 uint32 grfid = buf->ReadDWord();
05428 SoundID sound_id = buf->ReadWord();
05429
05430 file = GetFileByGRFID(grfid);
05431 if (file == NULL || file->sound_offset == 0) {
05432 grfmsg(1, "ImportGRFSound: Source file not available");
05433 return;
05434 }
05435
05436 if (file->sound_offset + sound_id >= GetNumSounds()) {
05437 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
05438 return;
05439 }
05440
05441 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
05442
05443 *sound = *GetSound(file->sound_offset + sound_id);
05444
05445
05446 sound->volume = 128;
05447 sound->priority = 0;
05448 }
05449
05450
05451 static void GRFImportBlock(ByteReader *buf)
05452 {
05453 if (_grf_data_blocks == 0) {
05454 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
05455 return;
05456 }
05457
05458 _grf_data_blocks--;
05459
05460
05461
05462 if (buf->ReadByte() != _grf_data_type) {
05463 grfmsg(1, "GRFImportBlock: Import type mismatch");
05464 }
05465
05466 switch (_grf_data_type) {
05467 case GDT_SOUND: ImportGRFSound(buf); break;
05468 default: NOT_REACHED();
05469 }
05470 }
05471
05472 static void LoadGRFSound(ByteReader *buf)
05473 {
05474
05475
05476 SoundEntry *sound = AllocateSound();
05477
05478 if (buf->ReadDWord() != BSWAP32('RIFF')) {
05479 grfmsg(1, "LoadGRFSound: Missing RIFF header");
05480 return;
05481 }
05482
05483 uint32 total_size = buf->ReadDWord();
05484 if (total_size > buf->Remaining()) {
05485 grfmsg(1, "LoadGRFSound: RIFF was truncated");
05486 return;
05487 }
05488
05489 if (buf->ReadDWord() != BSWAP32('WAVE')) {
05490 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
05491 return;
05492 }
05493
05494 while (total_size >= 8) {
05495 uint32 tag = buf->ReadDWord();
05496 uint32 size = buf->ReadDWord();
05497 total_size -= 8;
05498 if (total_size < size) {
05499 grfmsg(1, "LoadGRFSound: Invalid RIFF");
05500 return;
05501 }
05502 total_size -= size;
05503
05504 switch (tag) {
05505 case ' tmf':
05506
05507 if (size < 16 || buf->ReadWord() != 1) {
05508 grfmsg(1, "LoadGRFSound: Invalid audio format");
05509 return;
05510 }
05511 sound->channels = buf->ReadWord();
05512 sound->rate = buf->ReadDWord();
05513 buf->ReadDWord();
05514 buf->ReadWord();
05515 sound->bits_per_sample = buf->ReadWord();
05516
05517
05518 size -= 16;
05519 break;
05520
05521 case 'atad':
05522 sound->file_size = size;
05523 sound->file_offset = FioGetPos() - buf->Remaining();
05524 sound->file_slot = _file_index;
05525
05526
05527 sound->volume = 0x80;
05528 sound->priority = 0;
05529
05530 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
05531 return;
05532
05533 default:
05534
05535 break;
05536 }
05537
05538
05539 for (; size > 0; size--) buf->ReadByte();
05540 }
05541
05542 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
05543
05544
05545 MemSetT(sound, 0);
05546 }
05547
05548
05549 static void LoadFontGlyph(ByteReader *buf)
05550 {
05551
05552
05553
05554
05555
05556
05557
05558 uint8 num_def = buf->ReadByte();
05559
05560 for (uint i = 0; i < num_def; i++) {
05561 FontSize size = (FontSize)buf->ReadByte();
05562 uint8 num_char = buf->ReadByte();
05563 uint16 base_char = buf->ReadWord();
05564
05565 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
05566
05567 for (uint c = 0; c < num_char; c++) {
05568 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
05569 _nfo_line++;
05570 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
05571 }
05572 }
05573 }
05574
05575
05576 static void SkipAct12(ByteReader *buf)
05577 {
05578
05579
05580
05581
05582
05583
05584
05585 uint8 num_def = buf->ReadByte();
05586
05587 for (uint i = 0; i < num_def; i++) {
05588
05589 buf->ReadByte();
05590
05591
05592 _skip_sprites += buf->ReadByte();
05593
05594
05595 buf->ReadWord();
05596 }
05597
05598 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
05599 }
05600
05601
05602 static void TranslateGRFStrings(ByteReader *buf)
05603 {
05604
05605
05606
05607
05608
05609
05610
05611 uint32 grfid = buf->ReadDWord();
05612 const GRFConfig *c = GetGRFConfig(grfid);
05613 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
05614 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
05615 return;
05616 }
05617
05618 if (c->status == GCS_INITIALISED) {
05619
05620
05621 delete _cur_grfconfig->error;
05622 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_LOAD_AFTER);
05623
05624 char tmp[256];
05625 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
05626 _cur_grfconfig->error->data = strdup(tmp);
05627
05628 _cur_grfconfig->status = GCS_DISABLED;
05629 ClearTemporaryNewGRFData(_cur_grffile);
05630 _skip_sprites = -1;
05631 return;
05632 }
05633
05634 byte num_strings = buf->ReadByte();
05635 uint16 first_id = buf->ReadWord();
05636
05637 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
05638 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
05639 return;
05640 }
05641
05642 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
05643 const char *string = buf->ReadString();
05644
05645 if (StrEmpty(string)) {
05646 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
05647 continue;
05648 }
05649
05650
05651
05652
05653
05654
05655 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
05656 }
05657 }
05658
05659
05660 static void GRFDataBlock(ByteReader *buf)
05661 {
05662
05663
05664 if (_grf_data_blocks == 0) {
05665 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
05666 return;
05667 }
05668
05669 uint8 name_len = buf->ReadByte();
05670 const char *name = reinterpret_cast<const char *>(buf->Data());
05671 buf->Skip(name_len);
05672
05673
05674 if (buf->ReadByte() != 0) {
05675 grfmsg(2, "GRFDataBlock: Name not properly terminated");
05676 return;
05677 }
05678
05679 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
05680
05681 _grf_data_blocks--;
05682
05683 switch (_grf_data_type) {
05684 case GDT_SOUND: LoadGRFSound(buf); break;
05685 default: NOT_REACHED();
05686 }
05687 }
05688
05689
05690
05691 static void GRFUnsafe(ByteReader *buf)
05692 {
05693 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05694
05695
05696 _skip_sprites = -1;
05697 }
05698
05699
05700 static void InitializeGRFSpecial()
05701 {
05702 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
05703 | (1 << 0x0D)
05704 | (1 << 0x0E)
05705 | ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)
05706 | (0 << 0x10)
05707 | (1 << 0x12)
05708 | (1 << 0x13)
05709 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
05710 | (1 << 0x1B)
05711 | (1 << 0x1D)
05712 | (1 << 0x1E);
05713
05714 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
05715 | ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)
05716 | (1 << 0x09)
05717 | (0 << 0x0B)
05718 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
05719 | (1 << 0x12)
05720 | (1 << 0x13)
05721 | (1 << 0x14)
05722 | (1 << 0x16)
05723 | (1 << 0x17)
05724 | (1 << 0x18)
05725 | (1 << 0x19)
05726 | (1 << 0x1A)
05727 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
05728 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
05729
05730 _ttdpatch_flags[2] = (1 << 0x01)
05731 | (1 << 0x03)
05732 | (0 << 0x0B)
05733 | (0 << 0x0C)
05734 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
05735 | (1 << 0x0E)
05736 | (1 << 0x0F)
05737 | (0 << 0x10)
05738 | (0 << 0x11)
05739 | (1 << 0x12)
05740 | (1 << 0x13)
05741 | (1 << 0x14)
05742 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
05743 | (1 << 0x16)
05744 | (1 << 0x17)
05745 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
05746 | (1 << 0x19)
05747 | (1 << 0x1A)
05748 | (1 << 0x1B)
05749 | (1 << 0x1C)
05750 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
05751 | (1 << 0x1E)
05752 | (0 << 0x1F);
05753
05754 _ttdpatch_flags[3] = (0 << 0x00)
05755 | (1 << 0x01)
05756 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
05757 | (1 << 0x03)
05758 | (0 << 0x04)
05759 | (1 << 0x05)
05760 | (1 << 0x06)
05761 | (1 << 0x07)
05762 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
05763 | (0 << 0x09)
05764 | (0 << 0x0A)
05765 | (1 << 0x0B)
05766 | (1 << 0x0C)
05767 | (1 << 0x0D)
05768 | ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)
05769 | (1 << 0x0F)
05770 | (1 << 0x10)
05771 | (1 << 0x11)
05772 | (1 << 0x12)
05773 | (0 << 0x13)
05774 | (1 << 0x14)
05775 | (0 << 0x15)
05776 | (1 << 0x16)
05777 | (1 << 0x17)
05778 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
05779 | (1 << 0x1E)
05780 | (1 << 0x1F);
05781 }
05782
05783 static void ResetCustomStations()
05784 {
05785 const GRFFile * const *end = _grf_files.End();
05786 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05787 StationSpec **&stations = (*file)->stations;
05788 if (stations == NULL) continue;
05789 for (uint i = 0; i < MAX_STATIONS; i++) {
05790 if (stations[i] == NULL) continue;
05791 StationSpec *statspec = stations[i];
05792
05793
05794 if (!statspec->copied_renderdata) {
05795 for (uint t = 0; t < statspec->tiles; t++) {
05796 free((void*)statspec->renderdata[t].seq);
05797 }
05798 free(statspec->renderdata);
05799 }
05800
05801
05802 if (!statspec->copied_layouts) {
05803 for (uint l = 0; l < statspec->lengths; l++) {
05804 for (uint p = 0; p < statspec->platforms[l]; p++) {
05805 free(statspec->layouts[l][p]);
05806 }
05807 free(statspec->layouts[l]);
05808 }
05809 free(statspec->layouts);
05810 free(statspec->platforms);
05811 }
05812
05813
05814 free(statspec);
05815 }
05816
05817
05818 free(stations);
05819 stations = NULL;
05820 }
05821 }
05822
05823 static void ResetCustomHouses()
05824 {
05825 const GRFFile * const *end = _grf_files.End();
05826 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05827 HouseSpec **&housespec = (*file)->housespec;
05828 if (housespec == NULL) continue;
05829 for (uint i = 0; i < HOUSE_MAX; i++) {
05830 free(housespec[i]);
05831 }
05832
05833 free(housespec);
05834 housespec = NULL;
05835 }
05836 }
05837
05838 static void ResetCustomIndustries()
05839 {
05840 const GRFFile * const *end = _grf_files.End();
05841 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05842 IndustrySpec **&industryspec = (*file)->industryspec;
05843 IndustryTileSpec **&indtspec = (*file)->indtspec;
05844
05845
05846
05847 if (industryspec != NULL) {
05848 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
05849 IndustrySpec *ind = industryspec[i];
05850 if (ind == NULL) continue;
05851
05852
05853 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
05854 free((void*)ind->random_sounds);
05855 }
05856
05857
05858 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
05859 for (int j = 0; j < ind->num_table; j++) {
05860
05861 free((void*)ind->table[j]);
05862 }
05863
05864 free((void*)ind->table);
05865 ind->table = NULL;
05866 }
05867
05868 free(ind);
05869 }
05870
05871 free(industryspec);
05872 industryspec = NULL;
05873 }
05874
05875 if (indtspec == NULL) continue;
05876 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
05877 free(indtspec[i]);
05878 }
05879
05880 free(indtspec);
05881 indtspec = NULL;
05882 }
05883 }
05884
05885 static void ResetNewGRF()
05886 {
05887 const GRFFile * const *end = _grf_files.End();
05888 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
05889 GRFFile *f = *file;
05890 free(f->filename);
05891 free(f->cargo_list);
05892 free(f->railtype_list);
05893 free(f);
05894 }
05895
05896 _grf_files.Clear();
05897 _cur_grffile = NULL;
05898 }
05899
05900 static void ResetNewGRFErrors()
05901 {
05902 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
05903 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
05904 delete c->error;
05905 c->error = NULL;
05906 }
05907 }
05908 }
05909
05914 static void ResetNewGRFData()
05915 {
05916 CleanUpStrings();
05917 CleanUpGRFTownNames();
05918
05919
05920 SetupEngines();
05921
05922
05923 ResetBridges();
05924
05925
05926 ResetRailTypes();
05927
05928
05929 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
05930
05931
05932 Engine *e;
05933 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
05934 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
05935 }
05936
05937
05938 memset(&_grm_engines, 0, sizeof(_grm_engines));
05939 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
05940
05941
05942 ResetGenericCallbacks();
05943
05944
05945 ResetPriceBaseMultipliers();
05946
05947
05948 ResetCurrencies();
05949
05950
05951 ResetCustomHouses();
05952 ResetHouses();
05953
05954
05955 ResetCustomIndustries();
05956 ResetIndustries();
05957
05958
05959 ResetStationClasses();
05960 ResetCustomStations();
05961
05962
05963 memset(_water_feature, 0, sizeof(_water_feature));
05964
05965
05966 ClearSnowLine();
05967
05968
05969 ResetNewGRF();
05970
05971
05972 ResetNewGRFErrors();
05973
05974
05975 SetupCargoForClimate(_settings_game.game_creation.landscape);
05976
05977
05978 _misc_grf_features = 0;
05979
05980 _loaded_newgrf_features.has_2CC = false;
05981 _loaded_newgrf_features.has_newhouses = false;
05982 _loaded_newgrf_features.has_newindustries = false;
05983 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
05984
05985
05986 _grf_id_overrides.clear();
05987
05988 InitializeSoundPool();
05989 _spritegroup_pool.CleanPool();
05990 }
05991
05992 static void BuildCargoTranslationMap()
05993 {
05994 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
05995
05996 for (CargoID c = 0; c < NUM_CARGO; c++) {
05997 const CargoSpec *cs = CargoSpec::Get(c);
05998 if (!cs->IsValid()) continue;
05999
06000 if (_cur_grffile->cargo_max == 0) {
06001
06002 _cur_grffile->cargo_map[c] = cs->bitnum;
06003 } else {
06004
06005 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
06006 if (cs->label == _cur_grffile->cargo_list[i]) {
06007 _cur_grffile->cargo_map[c] = i;
06008 break;
06009 }
06010 }
06011 }
06012 }
06013 }
06014
06015 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
06016 {
06017 GRFFile *newfile = GetFileByFilename(config->filename);
06018 if (newfile != NULL) {
06019
06020 newfile->sprite_offset = sprite_offset;
06021 _cur_grffile = newfile;
06022 return;
06023 }
06024
06025 newfile = CallocT<GRFFile>(1);
06026
06027 if (newfile == NULL) error ("Out of memory");
06028
06029 newfile->filename = strdup(config->filename);
06030 newfile->sprite_offset = sprite_offset;
06031
06032
06033 newfile->traininfo_vehicle_pitch = 0;
06034 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
06035
06036
06037 for (Price i = PR_BEGIN; i < PR_END; i++) {
06038 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
06039 }
06040
06041
06042 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
06043 newfile->railtype_map[0] = RAILTYPE_RAIL;
06044 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
06045 newfile->railtype_map[2] = RAILTYPE_MONO;
06046 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
06047
06048
06049
06050 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
06051 memset(newfile->param, 0, sizeof(newfile->param));
06052
06053 assert(config->num_params <= lengthof(config->param));
06054 newfile->param_end = config->num_params;
06055 if (newfile->param_end > 0) {
06056 MemCpyT(newfile->param, config->param, newfile->param_end);
06057 }
06058
06059 *_grf_files.Append() = _cur_grffile = newfile;
06060 }
06061
06062
06065 static const CargoLabel _default_refitmasks_rail[] = {
06066 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
06067 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
06068 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
06069 'PLST', 'FZDR',
06070 0 };
06071
06072 static const CargoLabel _default_refitmasks_road[] = {
06073 0 };
06074
06075 static const CargoLabel _default_refitmasks_ships[] = {
06076 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
06077 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
06078 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
06079 'PLST', 'FZDR',
06080 0 };
06081
06082 static const CargoLabel _default_refitmasks_aircraft[] = {
06083 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
06084 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
06085 0 };
06086
06087 static const CargoLabel * const _default_refitmasks[] = {
06088 _default_refitmasks_rail,
06089 _default_refitmasks_road,
06090 _default_refitmasks_ships,
06091 _default_refitmasks_aircraft,
06092 };
06093
06094
06098 static void CalculateRefitMasks()
06099 {
06100 Engine *e;
06101
06102 FOR_ALL_ENGINES(e) {
06103 EngineID engine = e->index;
06104 EngineInfo *ei = &e->info;
06105 uint32 mask = 0;
06106 uint32 not_mask = 0;
06107 uint32 xor_mask = 0;
06108
06109
06110 if (_gted[engine].refitmask_valid) {
06111 if (ei->refit_mask != 0) {
06112 const GRFFile *file = e->grffile;
06113 if (file != NULL && file->cargo_max != 0) {
06114
06115 uint num_cargo = min(32, file->cargo_max);
06116 for (uint i = 0; i < num_cargo; i++) {
06117 if (!HasBit(ei->refit_mask, i)) continue;
06118
06119 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
06120 if (c == CT_INVALID) continue;
06121
06122 SetBit(xor_mask, c);
06123 }
06124 } else {
06125
06126 const CargoSpec *cs;
06127 FOR_ALL_CARGOSPECS(cs) {
06128 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
06129 }
06130 }
06131 }
06132
06133 if (_gted[engine].cargo_allowed != 0) {
06134
06135 const CargoSpec *cs;
06136 FOR_ALL_CARGOSPECS(cs) {
06137 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
06138 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
06139 }
06140 }
06141 } else {
06142
06143 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
06144 const CargoLabel *cl = _default_refitmasks[e->type];
06145 for (uint i = 0;; i++) {
06146 if (cl[i] == 0) break;
06147
06148 CargoID cargo = GetCargoIDByLabel(cl[i]);
06149 if (cargo == CT_INVALID) continue;
06150
06151 SetBit(xor_mask, cargo);
06152 }
06153 }
06154 }
06155
06156 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
06157
06158
06159
06160 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
06161 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
06162
06163
06164 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
06165 }
06166 }
06167
06169 static void FinaliseEngineArray()
06170 {
06171 Engine *e;
06172
06173 FOR_ALL_ENGINES(e) {
06174 if (e->grffile == NULL) {
06175 const EngineIDMapping &eid = _engine_mngr[e->index];
06176 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
06177 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
06178 }
06179 }
06180 }
06181 }
06182
06184 static void FinaliseCargoArray()
06185 {
06186 for (CargoID c = 0; c < NUM_CARGO; c++) {
06187 CargoSpec *cs = CargoSpec::Get(c);
06188 if (!cs->IsValid()) {
06189 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
06190 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
06191 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
06192 }
06193 }
06194 }
06195
06200 static void FinaliseHouseArray()
06201 {
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211 Year min_year = MAX_YEAR;
06212
06213 const GRFFile * const *end = _grf_files.End();
06214 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06215 HouseSpec **&housespec = (*file)->housespec;
06216 if (housespec == NULL) continue;
06217
06218 for (int i = 0; i < HOUSE_MAX; i++) {
06219 HouseSpec *hs = housespec[i];
06220
06221 if (hs == NULL) continue;
06222
06223 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
06224 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
06225 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
06226
06227 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
06228 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
06229 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
06230 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
06231 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
06232 hs->enabled = false;
06233 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", (*file)->filename, hs->local_id);
06234 continue;
06235 }
06236
06237
06238
06239
06240 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
06241 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
06242 hs->enabled = false;
06243 DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", (*file)->filename, hs->local_id);
06244 continue;
06245 }
06246
06247
06248 if ((hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->substitute_id)->building_flags & BUILDING_HAS_1_TILE)) {
06249 hs->enabled = false;
06250 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", (*file)->filename, hs->local_id);
06251 continue;
06252 }
06253
06254 _house_mngr.SetEntitySpec(hs);
06255 if (hs->min_year < min_year) min_year = hs->min_year;
06256 }
06257 }
06258
06259 if (min_year != 0) {
06260 for (int i = 0; i < HOUSE_MAX; i++) {
06261 HouseSpec *hs = HouseSpec::Get(i);
06262
06263 if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
06264 }
06265 }
06266 }
06267
06271 static void FinaliseIndustriesArray()
06272 {
06273 const GRFFile * const *end = _grf_files.End();
06274 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06275 IndustrySpec **&industryspec = (*file)->industryspec;
06276 IndustryTileSpec **&indtspec = (*file)->indtspec;
06277 if (industryspec != NULL) {
06278 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
06279 IndustrySpec *indsp = industryspec[i];
06280
06281 if (indsp != NULL && indsp->enabled) {
06282 StringID strid;
06283
06284
06285
06286 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
06287 if (strid != STR_UNDEFINED) indsp->name = strid;
06288
06289 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
06290 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
06291
06292 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
06293 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
06294
06295 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
06296 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
06297
06298 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
06299 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
06300
06301 if (indsp->station_name != STR_NULL) {
06302
06303
06304 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
06305 if (strid != STR_UNDEFINED) indsp->station_name = strid;
06306 }
06307
06308 _industry_mngr.SetEntitySpec(indsp);
06309 _loaded_newgrf_features.has_newindustries = true;
06310 }
06311 }
06312 }
06313
06314 if (indtspec != NULL) {
06315 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
06316 IndustryTileSpec *indtsp = indtspec[i];
06317 if (indtsp != NULL) {
06318 _industile_mngr.SetEntitySpec(indtsp);
06319 }
06320 }
06321 }
06322 }
06323
06324 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
06325 IndustrySpec *indsp = &_industry_specs[j];
06326 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
06327 for (uint i = 0; i < 3; i++) {
06328 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
06329 }
06330 }
06331 if (!indsp->enabled) {
06332 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
06333 }
06334 }
06335 }
06336
06337
06338
06339
06340
06341
06342
06343 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
06344 {
06345
06346
06347
06348
06349
06350
06351
06352
06353
06354
06355
06356
06357 static const SpecialSpriteHandler handlers[][GLS_END] = {
06358 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
06359 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
06360 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
06361 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
06362 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
06363 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
06364 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
06365 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
06366 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
06367 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
06368 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
06369 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
06370 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
06371 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
06372 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
06373 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
06374 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
06375 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
06376 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
06377 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
06378 };
06379
06380 GRFLocation location(_cur_grfconfig->grfid, _nfo_line);
06381
06382 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
06383 if (it == _grf_line_to_action6_sprite_override.end()) {
06384
06385
06386 FioReadBlock(buf, num);
06387 } else {
06388
06389 buf = _grf_line_to_action6_sprite_override[location];
06390 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
06391
06392
06393 FioSeekTo(num, SEEK_CUR);
06394 }
06395
06396 ByteReader br(buf, buf + num);
06397 ByteReader *bufp = &br;
06398
06399 try {
06400 byte action = bufp->ReadByte();
06401
06402 if (action == 0xFF) {
06403 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
06404 GRFDataBlock(bufp);
06405 } else if (action == 0xFE) {
06406 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
06407 GRFImportBlock(bufp);
06408 } else if (action >= lengthof(handlers)) {
06409 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
06410 } else if (handlers[action][stage] == NULL) {
06411 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
06412 } else {
06413 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
06414 handlers[action][stage](bufp);
06415 }
06416 } catch (...) {
06417 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
06418
06419 _skip_sprites = -1;
06420 _cur_grfconfig->status = GCS_DISABLED;
06421 delete _cur_grfconfig->error;
06422 _cur_grfconfig->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_READ_BOUNDS);
06423 }
06424 }
06425
06426
06427 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
06428 {
06429 const char *filename = config->filename;
06430 uint16 num;
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
06442 _cur_grffile = GetFileByFilename(filename);
06443 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
06444 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
06445 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
06446 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
06447 }
06448
06449 if (file_index > LAST_GRF_SLOT) {
06450 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
06451 config->status = GCS_DISABLED;
06452 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
06453 return;
06454 }
06455
06456 FioOpenFile(file_index, filename);
06457 _file_index = file_index;
06458 _palette_remap_grf[_file_index] = (config->windows_paletted != (_use_palette == PAL_WINDOWS));
06459
06460 _cur_grfconfig = config;
06461
06462 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
06463
06464
06465
06466
06467 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
06468 FioReadDword();
06469 } else {
06470 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
06471 return;
06472 }
06473
06474 _skip_sprites = 0;
06475 _nfo_line = 0;
06476
06477 ReusableBuffer<byte> buf;
06478
06479 while ((num = FioReadWord()) != 0) {
06480 byte type = FioReadByte();
06481 _nfo_line++;
06482
06483 if (type == 0xFF) {
06484 if (_skip_sprites == 0) {
06485 DecodeSpecialSprite(buf.Allocate(num), num, stage);
06486
06487
06488 if (_skip_sprites == -1) break;
06489
06490 continue;
06491 } else {
06492 FioSkipBytes(num);
06493 }
06494 } else {
06495 if (_skip_sprites == 0) {
06496 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
06497 config->status = GCS_DISABLED;
06498 delete config->error;
06499 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
06500 break;
06501 }
06502
06503 FioSkipBytes(7);
06504 SkipSpriteData(type, num - 8);
06505 }
06506
06507 if (_skip_sprites > 0) _skip_sprites--;
06508 }
06509 }
06510
06518 static void ActivateOldShore()
06519 {
06520
06521
06522 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06523
06524 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
06525 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
06526 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
06527 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
06528 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
06529 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
06530 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
06531 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
06532 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
06533 }
06534
06535 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
06536 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
06537 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
06538 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
06539 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
06540 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
06541 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
06542 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
06543 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
06544
06545
06546
06547 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
06548 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
06549 }
06550 }
06551
06555 static void FinalisePriceBaseMultipliers()
06556 {
06557 extern const PriceBaseSpec _price_base_specs[];
06558 static const uint32 override_features = (1 << GSF_TRAIN) | (1 << GSF_ROAD) | (1 << GSF_SHIP) | (1 << GSF_AIRCRAFT);
06559
06560
06561 int num_grfs = _grf_files.Length();
06562 int *grf_overrides = AllocaM(int, num_grfs);
06563 for (int i = 0; i < num_grfs; i++) {
06564 grf_overrides[i] = -1;
06565
06566 GRFFile *source = _grf_files[i];
06567 uint32 override = _grf_id_overrides[source->grfid];
06568 if (override == 0) continue;
06569
06570 GRFFile *dest = GetFileByGRFID(override);
06571 if (dest == NULL) continue;
06572
06573 grf_overrides[i] = _grf_files.FindIndex(dest);
06574 assert(grf_overrides[i] >= 0);
06575 }
06576
06577
06578 for (int i = 0; i < num_grfs; i++) {
06579 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
06580 GRFFile *source = _grf_files[i];
06581 GRFFile *dest = _grf_files[grf_overrides[i]];
06582
06583 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06584 source->grf_features |= features;
06585 dest->grf_features |= features;
06586
06587 for (Price p = PR_BEGIN; p < PR_END; p++) {
06588
06589 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
06590 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
06591 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06592 }
06593 }
06594
06595
06596 for (int i = num_grfs - 1; i >= 0; i--) {
06597 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
06598 GRFFile *source = _grf_files[i];
06599 GRFFile *dest = _grf_files[grf_overrides[i]];
06600
06601 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06602 source->grf_features |= features;
06603 dest->grf_features |= features;
06604
06605 for (Price p = PR_BEGIN; p < PR_END; p++) {
06606
06607 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
06608 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
06609 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
06610 }
06611 }
06612
06613
06614 for (int i = 0; i < num_grfs; i++) {
06615 if (grf_overrides[i] < 0) continue;
06616 GRFFile *source = _grf_files[i];
06617 GRFFile *dest = _grf_files[grf_overrides[i]];
06618
06619 uint32 features = (source->grf_features | dest->grf_features) & override_features;
06620 source->grf_features |= features;
06621 dest->grf_features |= features;
06622
06623 for (Price p = PR_BEGIN; p < PR_END; p++) {
06624 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
06625 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
06626 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
06627 }
06628 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
06629 }
06630 }
06631
06632
06633 const GRFFile * const *end = _grf_files.End();
06634 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06635 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06636 for (Price p = PR_BEGIN; p < PR_END; p++) {
06637 Price fallback_price = _price_base_specs[p].fallback_price;
06638 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06639
06640
06641 price_base_multipliers[p] = price_base_multipliers[fallback_price];
06642 }
06643 }
06644 }
06645
06646
06647 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
06648 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
06649 for (Price p = PR_BEGIN; p < PR_END; p++) {
06650 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
06651
06652 price_base_multipliers[p] = 0;
06653 } else {
06654 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
06655
06656
06657 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
06658 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
06659 price_base_multipliers[p] = 0;
06660 } else {
06661 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
06662 }
06663 }
06664 }
06665 }
06666 }
06667
06668 void InitDepotWindowBlockSizes();
06669
06670 extern void InitGRFTownGeneratorNames();
06671
06672 static void AfterLoadGRFs()
06673 {
06674 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
06675 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
06676 }
06677 _string_to_grf_mapping.clear();
06678
06679
06680 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
06681 free((*it).second);
06682 }
06683 _grf_line_to_action6_sprite_override.clear();
06684
06685
06686 FinaliseCargoArray();
06687
06688
06689 CalculateRefitMasks();
06690
06691
06692 FinaliseEngineArray();
06693
06694
06695 InitDepotWindowBlockSizes();
06696
06697
06698 FinaliseHouseArray();
06699
06700
06701 FinaliseIndustriesArray();
06702
06703
06704 BuildIndustriesLegend();
06705
06706
06707 InitGRFTownGeneratorNames();
06708
06709
06710 CommitVehicleListOrderChanges();
06711
06712
06713 ActivateOldShore();
06714
06715
06716 InitRailTypes();
06717
06718 Engine *e;
06719 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
06720 if (_gted[e->index].rv_max_speed != 0) {
06721
06722 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
06723 }
06724 }
06725
06726 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
06727 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
06728 if (railtype == INVALID_RAILTYPE) {
06729
06730 e->info.climates = 0x80;
06731 } else {
06732 e->u.rail.railtype = railtype;
06733 }
06734 }
06735
06736 SetYearEngineAgingStops();
06737
06738 FinalisePriceBaseMultipliers();
06739
06740
06741 free(_gted);
06742 _grm_sprites.clear();
06743 }
06744
06745 void LoadNewGRF(uint load_index, uint file_index)
06746 {
06747
06748
06749
06750
06751 Date date = _date;
06752 Year year = _cur_year;
06753 DateFract date_fract = _date_fract;
06754 uint16 tick_counter = _tick_counter;
06755 byte display_opt = _display_opt;
06756
06757 if (_networking) {
06758 _cur_year = _settings_game.game_creation.starting_year;
06759 _date = ConvertYMDToDate(_cur_year, 0, 1);
06760 _date_fract = 0;
06761 _tick_counter = 0;
06762 _display_opt = 0;
06763 }
06764
06765 InitializeGRFSpecial();
06766
06767 ResetNewGRFData();
06768
06769
06770
06771
06772
06773
06774
06775
06776 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06777 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
06778 }
06779
06780 _cur_spriteid = load_index;
06781
06782
06783
06784
06785 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
06786
06787
06788 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06789 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
06790 }
06791
06792 uint slot = file_index;
06793
06794 _cur_stage = stage;
06795 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06796 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
06797 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
06798
06799 if (!FioCheckFileExists(c->filename)) {
06800 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
06801 c->status = GCS_NOT_FOUND;
06802 continue;
06803 }
06804
06805 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
06806 LoadNewGRFFile(c, slot++, stage);
06807 if (stage == GLS_RESERVE) {
06808 SetBit(c->flags, GCF_RESERVED);
06809 } else if (stage == GLS_ACTIVATION) {
06810 ClrBit(c->flags, GCF_RESERVED);
06811 assert(GetFileByGRFID(c->grfid) == _cur_grffile);
06812 ClearTemporaryNewGRFData(_cur_grffile);
06813 BuildCargoTranslationMap();
06814 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
06815 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
06816
06817 ClearTemporaryNewGRFData(_cur_grffile);
06818 }
06819 }
06820 }
06821
06822
06823 AfterLoadGRFs();
06824
06825
06826 _cur_year = year;
06827 _date = date;
06828 _date_fract = date_fract;
06829 _tick_counter = tick_counter;
06830 _display_opt = display_opt;
06831 }
06832
06833 bool HasGrfMiscBit(GrfMiscBit bit)
06834 {
06835 return HasBit(_misc_grf_features, bit);
06836 }