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