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