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->group[ctype] = _cur_grffile->spritegroups[groupid];
04494 }
04495 }
04496 }
04497
04498
04499 buf->ReadWord();
04500 }
04501
04502 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
04503 {
04504 uint8 *airports = AllocaM(uint8, idcount);
04505 for (uint i = 0; i < idcount; i++) {
04506 airports[i] = buf->ReadByte();
04507 }
04508
04509
04510 uint8 cidcount = buf->ReadByte();
04511 buf->Skip(cidcount * 3);
04512
04513 uint16 groupid = buf->ReadWord();
04514 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
04515
04516 if (_cur_grffile->airportspec == NULL) {
04517 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
04518 return;
04519 }
04520
04521 for (uint i = 0; i < idcount; i++) {
04522 AirportSpec *as = _cur_grffile->airportspec[airports[i]];
04523
04524 if (as == NULL) {
04525 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
04526 continue;
04527 }
04528
04529 as->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04530 }
04531 }
04532
04533 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04534 {
04535 uint8 *airptiles = AllocaM(uint8, idcount);
04536 for (uint i = 0; i < idcount; i++) {
04537 airptiles[i] = buf->ReadByte();
04538 }
04539
04540
04541 uint8 cidcount = buf->ReadByte();
04542 buf->Skip(cidcount * 3);
04543
04544 uint16 groupid = buf->ReadWord();
04545 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
04546
04547 if (_cur_grffile->airtspec == NULL) {
04548 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
04549 return;
04550 }
04551
04552 for (uint i = 0; i < idcount; i++) {
04553 AirportTileSpec *airtsp = _cur_grffile->airtspec[airptiles[i]];
04554
04555 if (airtsp == NULL) {
04556 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
04557 continue;
04558 }
04559
04560 airtsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04561 }
04562 }
04563
04564
04565
04566 static void FeatureMapSpriteGroup(ByteReader *buf)
04567 {
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582 if (_cur_grffile->spritegroups == NULL) {
04583 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
04584 return;
04585 }
04586
04587 uint8 feature = buf->ReadByte();
04588 uint8 idcount = buf->ReadByte();
04589
04590
04591 if (idcount == 0) {
04592
04593 buf->ReadByte();
04594 uint16 groupid = buf->ReadWord();
04595 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
04596
04597 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
04598
04599 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
04600 return;
04601 }
04602
04603
04604 SetBit(_cur_grffile->grf_features, feature);
04605
04606 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
04607
04608 switch (feature) {
04609 case GSF_TRAINS:
04610 case GSF_ROADVEHICLES:
04611 case GSF_SHIPS:
04612 case GSF_AIRCRAFT:
04613 VehicleMapSpriteGroup(buf, feature, idcount);
04614 return;
04615
04616 case GSF_CANALS:
04617 CanalMapSpriteGroup(buf, idcount);
04618 return;
04619
04620 case GSF_STATIONS:
04621 StationMapSpriteGroup(buf, idcount);
04622 return;
04623
04624 case GSF_HOUSES:
04625 TownHouseMapSpriteGroup(buf, idcount);
04626 return;
04627
04628 case GSF_INDUSTRIES:
04629 IndustryMapSpriteGroup(buf, idcount);
04630 return;
04631
04632 case GSF_INDUSTRYTILES:
04633 IndustrytileMapSpriteGroup(buf, idcount);
04634 return;
04635
04636 case GSF_CARGOS:
04637 CargoMapSpriteGroup(buf, idcount);
04638 return;
04639
04640 case GSF_AIRPORTS:
04641 AirportMapSpriteGroup(buf, idcount);
04642 return;
04643
04644 case GSF_OBJECTS:
04645 ObjectMapSpriteGroup(buf, idcount);
04646 break;
04647
04648 case GSF_RAILTYPES:
04649 RailTypeMapSpriteGroup(buf, idcount);
04650 break;
04651
04652 case GSF_AIRPORTTILES:
04653 AirportTileMapSpriteGroup(buf, idcount);
04654 return;
04655
04656 default:
04657 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
04658 return;
04659 }
04660 }
04661
04662
04663 static void FeatureNewName(ByteReader *buf)
04664 {
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681 bool new_scheme = _cur_grffile->grf_version >= 7;
04682
04683 uint8 feature = buf->ReadByte();
04684 uint8 lang = buf->ReadByte();
04685 uint8 num = buf->ReadByte();
04686 bool generic = HasBit(lang, 7);
04687 uint16 id;
04688 if (generic) {
04689 id = buf->ReadWord();
04690 } else if (feature <= GSF_AIRCRAFT) {
04691 id = buf->ReadExtendedByte();
04692 } else {
04693 id = buf->ReadByte();
04694 }
04695
04696 ClrBit(lang, 7);
04697
04698 uint16 endid = id + num;
04699
04700 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
04701 id, endid, feature, lang);
04702
04703 for (; id < endid && buf->HasData(); id++) {
04704 const char *name = buf->ReadString();
04705 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
04706
04707 switch (feature) {
04708 case GSF_TRAINS:
04709 case GSF_ROADVEHICLES:
04710 case GSF_SHIPS:
04711 case GSF_AIRCRAFT:
04712 if (!generic) {
04713 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
04714 if (e == NULL) break;
04715 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
04716 e->info.string_id = string;
04717 } else {
04718 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04719 }
04720 break;
04721
04722 case GSF_INDUSTRIES: {
04723 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04724 break;
04725 }
04726
04727 case GSF_HOUSES:
04728 default:
04729 switch (GB(id, 8, 8)) {
04730 case 0xC4:
04731 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04732 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04733 } else {
04734 StationClassID cls_id = _cur_grffile->stations[GB(id, 0, 8)]->cls_id;
04735 StationClass::SetName(cls_id, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
04736 }
04737 break;
04738
04739 case 0xC5:
04740 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04741 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04742 } else {
04743 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04744 }
04745 break;
04746
04747 case 0xC7:
04748 if (_cur_grffile->airtspec == NULL || _cur_grffile->airtspec[GB(id, 0, 8)] == NULL) {
04749 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
04750 } else {
04751 _cur_grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04752 }
04753 break;
04754
04755 case 0xC9:
04756 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
04757 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
04758 } else {
04759 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04760 }
04761 break;
04762
04763 case 0xD0:
04764 case 0xD1:
04765 case 0xD2:
04766 case 0xD3:
04767 case 0xDC:
04768 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04769 break;
04770
04771 default:
04772 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
04773 break;
04774 }
04775 break;
04776 }
04777 }
04778 }
04779
04788 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
04789 {
04790
04791 if (offset >= max_sprites) {
04792 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
04793 uint orig_num = num;
04794 num = 0;
04795 return orig_num;
04796 }
04797
04798 if (offset + num > max_sprites) {
04799 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
04800 uint orig_num = num;
04801 num = max(max_sprites - offset, 0);
04802 return orig_num - num;
04803 }
04804
04805 return 0;
04806 }
04807
04808
04810 enum Action5BlockType {
04811 A5BLOCK_FIXED,
04812 A5BLOCK_ALLOW_OFFSET,
04813 A5BLOCK_INVALID,
04814 };
04816 struct Action5Type {
04817 Action5BlockType block_type;
04818 SpriteID sprite_base;
04819 uint16 min_sprites;
04820 uint16 max_sprites;
04821 const char *name;
04822 };
04823
04825 static const Action5Type _action5_types[] = {
04826
04827 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
04828 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
04829 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
04830 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
04831 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
04832 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
04833 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
04834 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
04835 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
04836 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
04837 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
04838 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
04839 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
04840 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
04841 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
04842 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
04843 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
04844 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
04845 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
04846 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
04847 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
04848 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
04849 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
04850 };
04851
04852
04853 static void GraphicsNew(ByteReader *buf)
04854 {
04855
04856
04857
04858
04859
04860
04861
04862 uint8 type = buf->ReadByte();
04863 uint16 num = buf->ReadExtendedByte();
04864 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
04865 ClrBit(type, 7);
04866
04867 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
04868
04869
04870 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
04871 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
04872 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
04873 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
04874 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
04875 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
04876 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
04877 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
04878 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
04879 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
04880 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
04881 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
04882 return;
04883 }
04884
04885
04886 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
04887 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
04888 _skip_sprites = num;
04889 return;
04890 }
04891
04892 const Action5Type *action5_type = &_action5_types[type];
04893
04894
04895 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
04896 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
04897 offset = 0;
04898 }
04899
04900
04901
04902 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
04903 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);
04904 _skip_sprites = num;
04905 return;
04906 }
04907
04908
04909 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
04910 SpriteID replace = action5_type->sprite_base + offset;
04911
04912
04913 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);
04914
04915 for (; num > 0; num--) {
04916 _nfo_line++;
04917 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
04918 }
04919
04920 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
04921
04922 _skip_sprites = skip_num;
04923 }
04924
04925
04926 static void SkipAct5(ByteReader *buf)
04927 {
04928
04929 buf->ReadByte();
04930
04931
04932 _skip_sprites = buf->ReadExtendedByte();
04933
04934 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
04935 }
04936
04942 void CheckForMissingSprites()
04943 {
04944
04945
04946 bool missing = false;
04947 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
04948 const Action5Type *type = &_action5_types[i];
04949 if (type->block_type == A5BLOCK_INVALID) continue;
04950
04951 for (uint j = 0; j < type->max_sprites; j++) {
04952 if (!SpriteExists(type->sprite_base + j)) {
04953 DEBUG(grf, 0, "%s sprites are missing", type->name);
04954 missing = true;
04955
04956 break;
04957 }
04958 }
04959 }
04960
04961 if (missing) {
04962 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
04963 }
04964 }
04965
04976 bool GetGlobalVariable(byte param, uint32 *value)
04977 {
04978 switch (param) {
04979 case 0x00:
04980 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
04981 return true;
04982
04983 case 0x01:
04984 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
04985 return true;
04986
04987 case 0x02: {
04988 YearMonthDay ymd;
04989 ConvertDateToYMD(_date, &ymd);
04990 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
04991 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
04992 return true;
04993 }
04994
04995 case 0x03:
04996 *value = _settings_game.game_creation.landscape;
04997 return true;
04998
04999 case 0x06:
05000 *value = _settings_game.vehicle.road_side << 4;
05001 return true;
05002
05003 case 0x09:
05004 *value = _date_fract * 885;
05005 return true;
05006
05007 case 0x0A:
05008 *value = _tick_counter;
05009 return true;
05010
05011 case 0x0B: {
05012 uint major = 2;
05013 uint minor = 6;
05014 uint revision = 1;
05015 uint build = 1382;
05016 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05017 return true;
05018 }
05019
05020 case 0x0D:
05021 *value = _cur_grfconfig->palette & GRFP_USE_MASK;
05022 return true;
05023
05024 case 0x0E:
05025 *value = _cur_grffile->traininfo_vehicle_pitch;
05026 return true;
05027
05028 case 0x0F:
05029 *value = 0;
05030 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
05031 if (_settings_game.vehicle.disable_elrails) {
05032
05033 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05034 } else {
05035 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05036
05037 }
05038 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05039 return true;
05040
05041 case 0x11:
05042 *value = 0;
05043 return true;
05044
05045 case 0x12:
05046 *value = _game_mode;
05047 return true;
05048
05049
05050
05051
05052
05053
05054
05055 case 0x1A:
05056 *value = UINT_MAX;
05057 return true;
05058
05059 case 0x1B:
05060 *value = GB(_display_opt, 0, 6);
05061 return true;
05062
05063 case 0x1D:
05064 *value = 1;
05065 return true;
05066
05067 case 0x1E:
05068 *value = _misc_grf_features;
05069
05070
05071 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05072 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05073 return true;
05074
05075
05076
05077 case 0x20:
05078 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
05079 return true;
05080
05081 case 0x21:
05082 *value = _openttd_newgrf_version;
05083 return true;
05084
05085 case 0x22:
05086 *value = _settings_game.difficulty.diff_level;
05087 return true;
05088
05089 case 0x23:
05090 *value = _date;
05091 return true;
05092
05093 case 0x24:
05094 *value = _cur_year;
05095 return true;
05096
05097 default: return false;
05098 }
05099 }
05100
05101 static uint32 GetParamVal(byte param, uint32 *cond_val)
05102 {
05103
05104 uint32 value;
05105 if (GetGlobalVariable(param - 0x80, &value)) return value;
05106
05107
05108 switch (param) {
05109 case 0x84: {
05110 uint32 res = 0;
05111
05112 if (_cur_stage > GLS_INIT) SetBit(res, 0);
05113 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
05114 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
05115 return res;
05116 }
05117
05118 case 0x85:
05119 if (cond_val == NULL) {
05120
05121 return 0;
05122 } else {
05123 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05124 *cond_val %= 0x20;
05125 return param_val;
05126 }
05127
05128 case 0x88:
05129 return 0;
05130
05131
05132
05133 default:
05134
05135 if (param < 0x80) return _cur_grffile->GetParam(param);
05136
05137
05138 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05139 return UINT_MAX;
05140 }
05141 }
05142
05143
05144 static void CfgApply(ByteReader *buf)
05145 {
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158 size_t pos = FioGetPos();
05159 uint16 num = FioReadWord();
05160 uint8 type = FioReadByte();
05161 byte *preload_sprite = NULL;
05162
05163
05164 if (type == 0xFF) {
05165 preload_sprite = MallocT<byte>(num);
05166 FioReadBlock(preload_sprite, num);
05167 }
05168
05169
05170 FioSeekTo(pos, SEEK_SET);
05171
05172 if (type != 0xFF) {
05173 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05174 free(preload_sprite);
05175 return;
05176 }
05177
05178 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line + 1);
05179 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05180 if (it != _grf_line_to_action6_sprite_override.end()) {
05181 free(preload_sprite);
05182 preload_sprite = _grf_line_to_action6_sprite_override[location];
05183 } else {
05184 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05185 }
05186
05187
05188
05189 for (;;) {
05190 uint i;
05191 uint param_num;
05192 uint param_size;
05193 uint offset;
05194 bool add_value;
05195
05196
05197 param_num = buf->ReadByte();
05198 if (param_num == 0xFF) break;
05199
05200
05201
05202 param_size = buf->ReadByte();
05203
05204
05205
05206 add_value = HasBit(param_size, 7);
05207 param_size = GB(param_size, 0, 7);
05208
05209
05210 offset = buf->ReadExtendedByte();
05211
05212
05213
05214 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
05215 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05216 break;
05217 }
05218
05219 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05220
05221 bool carry = false;
05222 for (i = 0; i < param_size && offset + i < num; i++) {
05223 uint32 value = GetParamVal(param_num + i / 4, NULL);
05224
05225
05226 if (i % 4 == 0) carry = false;
05227
05228 if (add_value) {
05229 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05230 preload_sprite[offset + i] = GB(new_value, 0, 8);
05231
05232 carry = new_value >= 256;
05233 } else {
05234 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05235 }
05236 }
05237 }
05238 }
05239
05249 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05250 {
05251 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05252 error->data = strdup(_cur_grfconfig->GetName());
05253 }
05254
05255
05256
05257 static void SkipIf(ByteReader *buf)
05258 {
05259
05260
05261
05262
05263
05264
05265
05266
05267 uint32 cond_val = 0;
05268 uint32 mask = 0;
05269 bool result;
05270
05271 uint8 param = buf->ReadByte();
05272 uint8 paramsize = buf->ReadByte();
05273 uint8 condtype = buf->ReadByte();
05274
05275 if (condtype < 2) {
05276
05277 paramsize = 1;
05278 }
05279
05280 switch (paramsize) {
05281 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05282 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05283 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05284 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05285 default: break;
05286 }
05287
05288 if (param < 0x80 && _cur_grffile->param_end <= param) {
05289 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05290 return;
05291 }
05292
05293 uint32 param_val = GetParamVal(param, &cond_val);
05294
05295 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05306
05307
05308 GRFConfig *c = GetGRFConfig(cond_val, mask);
05309
05310 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05311 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05312 c = NULL;
05313 }
05314
05315 if (condtype != 10 && c == NULL) {
05316 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05317 return;
05318 }
05319
05320 switch (condtype) {
05321
05322 case 0x06:
05323 result = c->status == GCS_ACTIVATED;
05324 break;
05325
05326 case 0x07:
05327 result = c->status != GCS_ACTIVATED;
05328 break;
05329
05330 case 0x08:
05331 result = c->status == GCS_INITIALISED;
05332 break;
05333
05334 case 0x09:
05335 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05336 break;
05337
05338 case 0x0A:
05339
05340 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05341 break;
05342
05343 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05344 }
05345 } else {
05346
05347 switch (condtype) {
05348 case 0x00: result = !!(param_val & (1 << cond_val));
05349 break;
05350 case 0x01: result = !(param_val & (1 << cond_val));
05351 break;
05352 case 0x02: result = (param_val & mask) == cond_val;
05353 break;
05354 case 0x03: result = (param_val & mask) != cond_val;
05355 break;
05356 case 0x04: result = (param_val & mask) < cond_val;
05357 break;
05358 case 0x05: result = (param_val & mask) > cond_val;
05359 break;
05360 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05361 break;
05362 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05363 break;
05364 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
05365 break;
05366 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
05367 break;
05368
05369 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
05370 }
05371 }
05372
05373 if (!result) {
05374 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
05375 return;
05376 }
05377
05378 uint8 numsprites = buf->ReadByte();
05379
05380
05381
05382
05383
05384 GRFLabel *choice = NULL;
05385 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
05386 if (label->label != numsprites) continue;
05387
05388
05389 if (choice == NULL) choice = label;
05390
05391 if (label->nfo_line > _nfo_line) {
05392 choice = label;
05393 break;
05394 }
05395 }
05396
05397 if (choice != NULL) {
05398 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
05399 FioSeekTo(choice->pos, SEEK_SET);
05400 _nfo_line = choice->nfo_line;
05401 return;
05402 }
05403
05404 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
05405 _skip_sprites = numsprites;
05406 if (_skip_sprites == 0) {
05407
05408
05409
05410 _skip_sprites = -1;
05411
05412
05413 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
05414 DisableGrf();
05415 }
05416 }
05417 }
05418
05419
05420
05421 static void ScanInfo(ByteReader *buf)
05422 {
05423 uint8 grf_version = buf->ReadByte();
05424 uint32 grfid = buf->ReadDWord();
05425 const char *name = buf->ReadString();
05426
05427 _cur_grfconfig->ident.grfid = grfid;
05428
05429
05430 if (grf_version > 7) {
05431 SetBit(_cur_grfconfig->flags, GCF_INVALID);
05432 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);
05433 }
05434
05435
05436 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
05437
05438 AddGRFTextToList(&_cur_grfconfig->name->text, 0x7F, grfid, name);
05439
05440 if (buf->HasData()) {
05441 const char *info = buf->ReadString();
05442 AddGRFTextToList(&_cur_grfconfig->info->text, 0x7F, grfid, info);
05443 }
05444
05445
05446 _skip_sprites = -1;
05447 }
05448
05449
05450 static void GRFInfo(ByteReader *buf)
05451 {
05452
05453
05454
05455
05456
05457
05458
05459 uint8 version = buf->ReadByte();
05460 uint32 grfid = buf->ReadDWord();
05461 const char *name = buf->ReadString();
05462
05463 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
05464 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
05465 return;
05466 }
05467
05468 if (_cur_grffile->grfid != grfid) {
05469 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));
05470 _cur_grffile->grfid = grfid;
05471 }
05472
05473 _cur_grffile->grf_version = version;
05474 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
05475
05476
05477 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);
05478 }
05479
05480
05481 static void SpriteReplace(ByteReader *buf)
05482 {
05483
05484
05485
05486
05487
05488
05489
05490
05491 uint8 num_sets = buf->ReadByte();
05492
05493 for (uint i = 0; i < num_sets; i++) {
05494 uint8 num_sprites = buf->ReadByte();
05495 uint16 first_sprite = buf->ReadWord();
05496
05497 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
05498 i, num_sprites, first_sprite
05499 );
05500
05501 for (uint j = 0; j < num_sprites; j++) {
05502 int load_index = first_sprite + j;
05503 _nfo_line++;
05504 LoadNextSprite(load_index, _file_index, _nfo_line);
05505
05506
05507
05508 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
05509 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
05510 }
05511 }
05512 }
05513 }
05514
05515
05516 static void SkipActA(ByteReader *buf)
05517 {
05518 uint8 num_sets = buf->ReadByte();
05519
05520 for (uint i = 0; i < num_sets; i++) {
05521
05522 _skip_sprites += buf->ReadByte();
05523
05524 buf->ReadWord();
05525 }
05526
05527 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
05528 }
05529
05530
05531 static void GRFLoadError(ByteReader *buf)
05532 {
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548 static const StringID msgstr[] = {
05549 STR_NEWGRF_ERROR_VERSION_NUMBER,
05550 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
05551 STR_NEWGRF_ERROR_UNSET_SWITCH,
05552 STR_NEWGRF_ERROR_INVALID_PARAMETER,
05553 STR_NEWGRF_ERROR_LOAD_BEFORE,
05554 STR_NEWGRF_ERROR_LOAD_AFTER,
05555 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
05556 };
05557
05558 static const StringID sevstr[] = {
05559 STR_NEWGRF_ERROR_MSG_INFO,
05560 STR_NEWGRF_ERROR_MSG_WARNING,
05561 STR_NEWGRF_ERROR_MSG_ERROR,
05562 STR_NEWGRF_ERROR_MSG_FATAL
05563 };
05564
05565
05566 if (_cur_grfconfig->error != NULL) return;
05567
05568 byte severity = buf->ReadByte();
05569 byte lang = buf->ReadByte();
05570 byte message_id = buf->ReadByte();
05571
05572
05573 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
05574
05575
05576
05577 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
05578 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
05579 return;
05580 }
05581 ClrBit(severity, 7);
05582
05583 if (severity >= lengthof(sevstr)) {
05584 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
05585 severity = 2;
05586 } else if (severity == 3) {
05587
05588
05589 DisableGrf();
05590 }
05591
05592 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
05593 grfmsg(7, "GRFLoadError: Invalid message id.");
05594 return;
05595 }
05596
05597 if (buf->Remaining() <= 1) {
05598 grfmsg(7, "GRFLoadError: No message data supplied.");
05599 return;
05600 }
05601
05602 GRFError *error = new GRFError(sevstr[severity]);
05603
05604 if (message_id == 0xFF) {
05605
05606 if (buf->HasData()) {
05607 const char *message = buf->ReadString();
05608
05609 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, message);
05610 } else {
05611 grfmsg(7, "GRFLoadError: No custom message supplied.");
05612 error->custom_message = strdup("");
05613 }
05614 } else {
05615 error->message = msgstr[message_id];
05616 }
05617
05618 if (buf->HasData()) {
05619 const char *data = buf->ReadString();
05620
05621 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, data);
05622 } else {
05623 grfmsg(7, "GRFLoadError: No message data supplied.");
05624 error->data = strdup("");
05625 }
05626
05627
05628 uint i = 0;
05629 for (; i < 2 && buf->HasData(); i++) {
05630 uint param_number = buf->ReadByte();
05631 error->param_value[i] = _cur_grffile->GetParam(param_number);
05632 }
05633 error->num_params = i;
05634
05635 _cur_grfconfig->error = error;
05636 }
05637
05638
05639 static void GRFComment(ByteReader *buf)
05640 {
05641
05642
05643
05644
05645 if (!buf->HasData()) return;
05646
05647 const char *text = buf->ReadString();
05648 grfmsg(2, "GRFComment: %s", text);
05649 }
05650
05651
05652 static void SafeParamSet(ByteReader *buf)
05653 {
05654 uint8 target = buf->ReadByte();
05655
05656
05657 if (target < 0x80) return;
05658
05659
05660
05661
05662
05663
05664 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05665
05666
05667 _skip_sprites = -1;
05668 }
05669
05670
05671 static uint32 GetPatchVariable(uint8 param)
05672 {
05673 switch (param) {
05674
05675 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
05676
05677
05678 case 0x0E: return _settings_game.vehicle.freight_trains;
05679
05680
05681 case 0x0F: return 0;
05682
05683
05684
05685
05686 case 0x10:
05687 switch (_settings_game.vehicle.plane_speed) {
05688 default:
05689 case 4: return 1;
05690 case 3: return 2;
05691 case 2: return 2;
05692 case 1: return 4;
05693 }
05694
05695
05696
05697 case 0x11: return SPR_2CCMAP_BASE;
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710 case 0x13: {
05711 byte map_bits = 0;
05712 byte log_X = MapLogX() - 6;
05713 byte log_Y = MapLogY() - 6;
05714 byte max_edge = max(log_X, log_Y);
05715
05716 if (log_X == log_Y) {
05717 SetBit(map_bits, 0);
05718 } else {
05719 if (max_edge == log_Y) SetBit(map_bits, 1);
05720 }
05721
05722 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
05723 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
05724 }
05725
05726 default:
05727 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
05728 return 0;
05729 }
05730 }
05731
05732
05733 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
05734 {
05735 uint start = 0;
05736 uint size = 0;
05737
05738 if (op == 6) {
05739
05740 return grm[_cur_grffile->GetParam(target)];
05741 }
05742
05743
05744 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
05745
05746 for (uint i = start; i < num_ids; i++) {
05747 if (grm[i] == 0) {
05748 size++;
05749 } else {
05750 if (op == 2 || op == 3) break;
05751 start = i + 1;
05752 size = 0;
05753 }
05754
05755 if (size == count) break;
05756 }
05757
05758 if (size == count) {
05759
05760 if (op == 0 || op == 3) {
05761 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
05762 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
05763 }
05764 return start;
05765 }
05766
05767
05768 if (op != 4 && op != 5) {
05769
05770 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
05771 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05772 return UINT_MAX;
05773 }
05774
05775 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
05776 return UINT_MAX;
05777 }
05778
05779
05780
05781 static void ParamSet(ByteReader *buf)
05782 {
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800
05801
05802
05803
05804
05805 uint8 target = buf->ReadByte();
05806 uint8 oper = buf->ReadByte();
05807 uint32 src1 = buf->ReadByte();
05808 uint32 src2 = buf->ReadByte();
05809
05810 uint32 data = 0;
05811 if (buf->Remaining() >= 4) data = buf->ReadDWord();
05812
05813
05814
05815
05816
05817
05818
05819 if (HasBit(oper, 7)) {
05820 if (target < 0x80 && target < _cur_grffile->param_end) {
05821 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
05822 return;
05823 }
05824
05825 oper = GB(oper, 0, 7);
05826 }
05827
05828 if (src2 == 0xFE) {
05829 if (GB(data, 0, 8) == 0xFF) {
05830 if (data == 0x0000FFFF) {
05831
05832 src1 = GetPatchVariable(src1);
05833 } else {
05834
05835 uint8 op = src1;
05836 uint8 feature = GB(data, 8, 8);
05837 uint16 count = GB(data, 16, 16);
05838
05839 if (_cur_stage == GLS_RESERVE) {
05840 if (feature == 0x08) {
05841
05842 if (op == 0) {
05843
05844 if (_cur_spriteid + count >= 16384) {
05845 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
05846 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05847 return;
05848 }
05849
05850
05851 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
05852 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
05853 _cur_spriteid += count;
05854 }
05855 }
05856
05857 src1 = 0;
05858 } else if (_cur_stage == GLS_ACTIVATION) {
05859 switch (feature) {
05860 case 0x00:
05861 case 0x01:
05862 case 0x02:
05863 case 0x03:
05864 if (!_settings_game.vehicle.dynamic_engines) {
05865 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
05866 if (_skip_sprites == -1) return;
05867 } else {
05868
05869 switch (op) {
05870 case 2:
05871 case 3:
05872 src1 = _cur_grffile->GetParam(target);
05873 break;
05874
05875 default:
05876 src1 = 0;
05877 break;
05878 }
05879 }
05880 break;
05881
05882 case 0x08:
05883 switch (op) {
05884 case 0:
05885
05886 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
05887 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
05888 break;
05889
05890 case 1:
05891 src1 = _cur_spriteid;
05892 break;
05893
05894 default:
05895 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
05896 return;
05897 }
05898 break;
05899
05900 case 0x0B:
05901
05902 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
05903 if (_skip_sprites == -1) return;
05904 break;
05905
05906 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
05907 }
05908 } else {
05909
05910 src1 = 0;
05911 }
05912 }
05913 } else {
05914
05915 const GRFFile *file = GetFileByGRFID(data);
05916 GRFConfig *c = GetGRFConfig(data);
05917 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05918
05919 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05920 src1 = 0;
05921 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
05922 src1 = 0;
05923 } else if (src1 == 0xFE) {
05924 src1 = c->version;
05925 } else {
05926 src1 = file->GetParam(src1);
05927 }
05928 }
05929 } else {
05930
05931
05932
05933
05934
05935 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
05936 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
05937 }
05938
05939
05940
05941
05942
05943
05944
05945 uint32 res;
05946 switch (oper) {
05947 case 0x00:
05948 res = src1;
05949 break;
05950
05951 case 0x01:
05952 res = src1 + src2;
05953 break;
05954
05955 case 0x02:
05956 res = src1 - src2;
05957 break;
05958
05959 case 0x03:
05960 res = src1 * src2;
05961 break;
05962
05963 case 0x04:
05964 res = (int32)src1 * (int32)src2;
05965 break;
05966
05967 case 0x05:
05968 if ((int32)src2 < 0) {
05969 res = src1 >> -(int32)src2;
05970 } else {
05971 res = src1 << src2;
05972 }
05973 break;
05974
05975 case 0x06:
05976 if ((int32)src2 < 0) {
05977 res = (int32)src1 >> -(int32)src2;
05978 } else {
05979 res = (int32)src1 << src2;
05980 }
05981 break;
05982
05983 case 0x07:
05984 res = src1 & src2;
05985 break;
05986
05987 case 0x08:
05988 res = src1 | src2;
05989 break;
05990
05991 case 0x09:
05992 if (src2 == 0) {
05993 res = src1;
05994 } else {
05995 res = src1 / src2;
05996 }
05997 break;
05998
05999 case 0x0A:
06000 if (src2 == 0) {
06001 res = src1;
06002 } else {
06003 res = (int32)src1 / (int32)src2;
06004 }
06005 break;
06006
06007 case 0x0B:
06008 if (src2 == 0) {
06009 res = src1;
06010 } else {
06011 res = src1 % src2;
06012 }
06013 break;
06014
06015 case 0x0C:
06016 if (src2 == 0) {
06017 res = src1;
06018 } else {
06019 res = (int32)src1 % (int32)src2;
06020 }
06021 break;
06022
06023 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06024 }
06025
06026 switch (target) {
06027 case 0x8E:
06028 _cur_grffile->traininfo_vehicle_pitch = res;
06029 break;
06030
06031 case 0x8F: {
06032 extern RailtypeInfo _railtypes[RAILTYPE_END];
06033 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06034 if (_settings_game.vehicle.disable_elrails) {
06035 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06036 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06037 } else {
06038 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06039 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06040 }
06041 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06042 break;
06043 }
06044
06045
06046 case 0x93:
06047 case 0x94:
06048 case 0x95:
06049 case 0x96:
06050 case 0x97:
06051 case 0x99:
06052 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06053 break;
06054
06055 case 0x9E:
06056 _misc_grf_features = res;
06057
06058
06059 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06060
06061
06062 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
06063 break;
06064
06065 case 0x9F:
06066 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06067 break;
06068
06069 default:
06070 if (target < 0x80) {
06071 _cur_grffile->param[target] = res;
06072
06073 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
06074 } else {
06075 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06076 }
06077 break;
06078 }
06079 }
06080
06081
06082 static void SafeGRFInhibit(ByteReader *buf)
06083 {
06084
06085
06086
06087
06088
06089 uint8 num = buf->ReadByte();
06090
06091 for (uint i = 0; i < num; i++) {
06092 uint32 grfid = buf->ReadDWord();
06093
06094
06095 if (grfid != _cur_grfconfig->ident.grfid) {
06096 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06097
06098
06099 _skip_sprites = -1;
06100
06101 return;
06102 }
06103 }
06104 }
06105
06106
06107 static void GRFInhibit(ByteReader *buf)
06108 {
06109
06110
06111
06112
06113
06114 uint8 num = buf->ReadByte();
06115
06116 for (uint i = 0; i < num; i++) {
06117 uint32 grfid = buf->ReadDWord();
06118 GRFConfig *file = GetGRFConfig(grfid);
06119
06120
06121 if (file != NULL && file != _cur_grfconfig) {
06122 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06123 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06124 error->data = strdup(_cur_grfconfig->GetName());
06125 }
06126 }
06127 }
06128
06129
06130 static void FeatureTownName(ByteReader *buf)
06131 {
06132
06133
06134
06135
06136
06137
06138
06139 uint32 grfid = _cur_grffile->grfid;
06140
06141 GRFTownName *townname = AddGRFTownName(grfid);
06142
06143 byte id = buf->ReadByte();
06144 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06145
06146 if (HasBit(id, 7)) {
06147
06148 ClrBit(id, 7);
06149 bool new_scheme = _cur_grffile->grf_version >= 7;
06150
06151 byte lang = buf->ReadByte();
06152
06153 byte nb_gen = townname->nb_gen;
06154 do {
06155 ClrBit(lang, 7);
06156
06157 const char *name = buf->ReadString();
06158
06159 char *lang_name = TranslateTTDPatchCodes(grfid, lang, name);
06160 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06161 free(lang_name);
06162
06163 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
06164
06165 lang = buf->ReadByte();
06166 } while (lang != 0);
06167 townname->id[nb_gen] = id;
06168 townname->nb_gen++;
06169 }
06170
06171 byte nb = buf->ReadByte();
06172 grfmsg(6, "FeatureTownName: %u parts", nb);
06173
06174 townname->nbparts[id] = nb;
06175 townname->partlist[id] = CallocT<NamePartList>(nb);
06176
06177 for (int i = 0; i < nb; i++) {
06178 byte nbtext = buf->ReadByte();
06179 townname->partlist[id][i].bitstart = buf->ReadByte();
06180 townname->partlist[id][i].bitcount = buf->ReadByte();
06181 townname->partlist[id][i].maxprob = 0;
06182 townname->partlist[id][i].partcount = nbtext;
06183 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06184 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);
06185
06186 for (int j = 0; j < nbtext; j++) {
06187 byte prob = buf->ReadByte();
06188
06189 if (HasBit(prob, 7)) {
06190 byte ref_id = buf->ReadByte();
06191
06192 if (townname->nbparts[ref_id] == 0) {
06193 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06194 DelGRFTownName(grfid);
06195 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06196 return;
06197 }
06198
06199 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06200 townname->partlist[id][i].parts[j].data.id = ref_id;
06201 } else {
06202 const char *text = buf->ReadString();
06203 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, text);
06204 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06205 }
06206 townname->partlist[id][i].parts[j].prob = prob;
06207 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06208 }
06209 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06210 }
06211 }
06212
06213
06214 static void DefineGotoLabel(ByteReader *buf)
06215 {
06216
06217
06218
06219
06220
06221 byte nfo_label = buf->ReadByte();
06222
06223 GRFLabel *label = MallocT<GRFLabel>(1);
06224 label->label = nfo_label;
06225 label->nfo_line = _nfo_line;
06226 label->pos = FioGetPos();
06227 label->next = NULL;
06228
06229
06230 if (_cur_grffile->label == NULL) {
06231 _cur_grffile->label = label;
06232 } else {
06233
06234 GRFLabel *l;
06235 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
06236 l->next = label;
06237 }
06238
06239 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06240 }
06241
06242
06243 static void GRFSound(ByteReader *buf)
06244 {
06245
06246
06247
06248
06249 uint16 num = buf->ReadWord();
06250
06251 _grf_data_blocks = num;
06252 _grf_data_type = GDT_SOUND;
06253
06254 if (_cur_grffile->sound_offset == 0) {
06255 _cur_grffile->sound_offset = GetNumSounds();
06256 _cur_grffile->num_sounds = num;
06257 }
06258 }
06259
06260
06261 static void SkipAct11(ByteReader *buf)
06262 {
06263
06264
06265
06266
06267 _skip_sprites = buf->ReadWord();
06268
06269 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
06270 }
06271
06272 static void ImportGRFSound(ByteReader *buf)
06273 {
06274 const GRFFile *file;
06275 SoundEntry *sound = AllocateSound();
06276 uint32 grfid = buf->ReadDWord();
06277 SoundID sound_id = buf->ReadWord();
06278
06279 file = GetFileByGRFID(grfid);
06280 if (file == NULL || file->sound_offset == 0) {
06281 grfmsg(1, "ImportGRFSound: Source file not available");
06282 return;
06283 }
06284
06285 if (sound_id >= file->num_sounds) {
06286 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06287 return;
06288 }
06289
06290 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06291
06292 *sound = *GetSound(file->sound_offset + sound_id);
06293
06294
06295 sound->volume = 128;
06296 sound->priority = 0;
06297 }
06298
06299
06300 static void GRFImportBlock(ByteReader *buf)
06301 {
06302 if (_grf_data_blocks == 0) {
06303 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
06304 return;
06305 }
06306
06307 _grf_data_blocks--;
06308
06309
06310
06311 if (buf->ReadByte() != _grf_data_type) {
06312 grfmsg(1, "GRFImportBlock: Import type mismatch");
06313 }
06314
06315 switch (_grf_data_type) {
06316 case GDT_SOUND: ImportGRFSound(buf); break;
06317 default: NOT_REACHED();
06318 }
06319 }
06320
06321 static void LoadGRFSound(ByteReader *buf)
06322 {
06323
06324
06325 SoundEntry *sound = AllocateSound();
06326
06327 if (buf->ReadDWord() != BSWAP32('RIFF')) {
06328 grfmsg(1, "LoadGRFSound: Missing RIFF header");
06329 return;
06330 }
06331
06332 uint32 total_size = buf->ReadDWord();
06333 if (total_size > buf->Remaining()) {
06334 grfmsg(1, "LoadGRFSound: RIFF was truncated");
06335 return;
06336 }
06337
06338 if (buf->ReadDWord() != BSWAP32('WAVE')) {
06339 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
06340 return;
06341 }
06342
06343 while (total_size >= 8) {
06344 uint32 tag = buf->ReadDWord();
06345 uint32 size = buf->ReadDWord();
06346 total_size -= 8;
06347 if (total_size < size) {
06348 grfmsg(1, "LoadGRFSound: Invalid RIFF");
06349 return;
06350 }
06351 total_size -= size;
06352
06353 switch (tag) {
06354 case ' tmf':
06355
06356 if (size < 16 || buf->ReadWord() != 1) {
06357 grfmsg(1, "LoadGRFSound: Invalid audio format");
06358 return;
06359 }
06360 sound->channels = buf->ReadWord();
06361 sound->rate = buf->ReadDWord();
06362 buf->ReadDWord();
06363 buf->ReadWord();
06364 sound->bits_per_sample = buf->ReadWord();
06365
06366
06367 size -= 16;
06368 break;
06369
06370 case 'atad':
06371 sound->file_size = size;
06372 sound->file_offset = FioGetPos() - buf->Remaining();
06373 sound->file_slot = _file_index;
06374
06375
06376 sound->volume = 0x80;
06377 sound->priority = 0;
06378
06379 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
06380 return;
06381
06382 default:
06383
06384 break;
06385 }
06386
06387
06388 for (; size > 0; size--) buf->ReadByte();
06389 }
06390
06391 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
06392
06393
06394 MemSetT(sound, 0);
06395 }
06396
06397
06398 static void LoadFontGlyph(ByteReader *buf)
06399 {
06400
06401
06402
06403
06404
06405
06406
06407 uint8 num_def = buf->ReadByte();
06408
06409 for (uint i = 0; i < num_def; i++) {
06410 FontSize size = (FontSize)buf->ReadByte();
06411 uint8 num_char = buf->ReadByte();
06412 uint16 base_char = buf->ReadWord();
06413
06414 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
06415
06416 for (uint c = 0; c < num_char; c++) {
06417 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
06418 _nfo_line++;
06419 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
06420 }
06421 }
06422 }
06423
06424
06425 static void SkipAct12(ByteReader *buf)
06426 {
06427
06428
06429
06430
06431
06432
06433
06434 uint8 num_def = buf->ReadByte();
06435
06436 for (uint i = 0; i < num_def; i++) {
06437
06438 buf->ReadByte();
06439
06440
06441 _skip_sprites += buf->ReadByte();
06442
06443
06444 buf->ReadWord();
06445 }
06446
06447 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
06448 }
06449
06450
06451 static void TranslateGRFStrings(ByteReader *buf)
06452 {
06453
06454
06455
06456
06457
06458
06459
06460 uint32 grfid = buf->ReadDWord();
06461 const GRFConfig *c = GetGRFConfig(grfid);
06462 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
06463 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
06464 return;
06465 }
06466
06467 if (c->status == GCS_INITIALISED) {
06468
06469
06470 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
06471
06472 char tmp[256];
06473 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
06474 error->data = strdup(tmp);
06475
06476 return;
06477 }
06478
06479 byte num_strings = buf->ReadByte();
06480 uint16 first_id = buf->ReadWord();
06481
06482 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
06483 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
06484 return;
06485 }
06486
06487 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
06488 const char *string = buf->ReadString();
06489
06490 if (StrEmpty(string)) {
06491 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
06492 continue;
06493 }
06494
06495
06496
06497
06498
06499
06500 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
06501 }
06502 }
06503
06505 static bool ChangeGRFName(byte langid, const char *str)
06506 {
06507 AddGRFTextToList(&_cur_grfconfig->name->text, langid, _cur_grfconfig->ident.grfid, str);
06508 return true;
06509 }
06510
06512 static bool ChangeGRFDescription(byte langid, const char *str)
06513 {
06514 AddGRFTextToList(&_cur_grfconfig->info->text, langid, _cur_grfconfig->ident.grfid, str);
06515 return true;
06516 }
06517
06519 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
06520 {
06521 if (len != 1) {
06522 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
06523 buf->Skip(len);
06524 } else {
06525 _cur_grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur_grfconfig->param));
06526 }
06527 return true;
06528 }
06529
06531 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
06532 {
06533 if (len != 1) {
06534 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
06535 buf->Skip(len);
06536 } else {
06537 char data = buf->ReadByte();
06538 GRFPalette pal = GRFP_GRF_UNSET;
06539 switch (data) {
06540 case '*':
06541 case 'A': pal = GRFP_GRF_ANY; break;
06542 case 'W': pal = GRFP_GRF_WINDOWS; break;
06543 case 'D': pal = GRFP_GRF_DOS; break;
06544 default:
06545 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
06546 break;
06547 }
06548 if (pal != GRFP_GRF_UNSET) {
06549 _cur_grfconfig->palette &= ~GRFP_GRF_MASK;
06550 _cur_grfconfig->palette |= pal;
06551 }
06552 }
06553 return true;
06554 }
06555
06557 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
06558 {
06559 if (len != 4) {
06560 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
06561 buf->Skip(len);
06562 } else {
06563
06564 _cur_grfconfig->version = _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06565 }
06566 return true;
06567 }
06568
06570 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
06571 {
06572 if (len != 4) {
06573 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
06574 buf->Skip(len);
06575 } else {
06576 _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06577 if (_cur_grfconfig->version == 0) {
06578 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
06579 _cur_grfconfig->min_loadable_version = 0;
06580 }
06581 if (_cur_grfconfig->version < _cur_grfconfig->min_loadable_version) {
06582 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur_grfconfig->min_loadable_version);
06583 _cur_grfconfig->min_loadable_version = _cur_grfconfig->version;
06584 }
06585 }
06586 return true;
06587 }
06588
06589 static GRFParameterInfo *_cur_parameter;
06590
06592 static bool ChangeGRFParamName(byte langid, const char *str)
06593 {
06594 AddGRFTextToList(&_cur_parameter->name, langid, _cur_grfconfig->ident.grfid, str);
06595 return true;
06596 }
06597
06599 static bool ChangeGRFParamDescription(byte langid, const char *str)
06600 {
06601 AddGRFTextToList(&_cur_parameter->desc, langid, _cur_grfconfig->ident.grfid, str);
06602 return true;
06603 }
06604
06606 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
06607 {
06608 if (len != 1) {
06609 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
06610 buf->Skip(len);
06611 } else {
06612 GRFParameterType type = (GRFParameterType)buf->ReadByte();
06613 if (type < PTYPE_END) {
06614 _cur_parameter->type = type;
06615 } else {
06616 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
06617 }
06618 }
06619 return true;
06620 }
06621
06623 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
06624 {
06625 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
06626 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
06627 buf->Skip(len);
06628 } else if (len != 8) {
06629 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
06630 buf->Skip(len);
06631 } else {
06632 _cur_parameter->min_value = buf->ReadDWord();
06633 _cur_parameter->max_value = buf->ReadDWord();
06634 }
06635 return true;
06636 }
06637
06639 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
06640 {
06641 if (len < 1 || len > 3) {
06642 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
06643 buf->Skip(len);
06644 } else {
06645 byte param_nr = buf->ReadByte();
06646 if (param_nr >= lengthof(_cur_grfconfig->param)) {
06647 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
06648 buf->Skip(len - 1);
06649 } else {
06650 _cur_parameter->param_nr = param_nr;
06651 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
06652 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
06653 }
06654 }
06655
06656 return true;
06657 }
06658
06660 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
06661 {
06662 if (len != 4) {
06663 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
06664 buf->Skip(len);
06665 } else {
06666 _cur_parameter->def_value = buf->ReadDWord();
06667 }
06668 _cur_grfconfig->has_param_defaults = true;
06669 return true;
06670 }
06671
06672 typedef bool (*DataHandler)(size_t, ByteReader *);
06673 typedef bool (*TextHandler)(byte, const char *str);
06674 typedef bool (*BranchHandler)(ByteReader *);
06675
06683 struct AllowedSubtags {
06685 AllowedSubtags() :
06686 id(0),
06687 type(0)
06688 {}
06689
06695 AllowedSubtags(uint32 id, DataHandler handler) :
06696 id(id),
06697 type('B')
06698 {
06699 this->handler.data = handler;
06700 }
06701
06707 AllowedSubtags(uint32 id, TextHandler handler) :
06708 id(id),
06709 type('T')
06710 {
06711 this->handler.text = handler;
06712 }
06713
06719 AllowedSubtags(uint32 id, BranchHandler handler) :
06720 id(id),
06721 type('C')
06722 {
06723 this->handler.call_handler = true;
06724 this->handler.u.branch = handler;
06725 }
06726
06732 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
06733 id(id),
06734 type('C')
06735 {
06736 this->handler.call_handler = false;
06737 this->handler.u.subtags = subtags;
06738 }
06739
06740 uint32 id;
06741 byte type;
06742 union {
06743 DataHandler data;
06744 TextHandler text;
06745 struct {
06746 union {
06747 BranchHandler branch;
06748 AllowedSubtags *subtags;
06749 } u;
06750 bool call_handler;
06751 };
06752 } handler;
06753 };
06754
06755 static bool SkipUnknownInfo(ByteReader *buf, byte type);
06756 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
06757
06764 static bool ChangeGRFParamValueNames(ByteReader *buf)
06765 {
06766 byte type = buf->ReadByte();
06767 while (type != 0) {
06768 uint32 id = buf->ReadDWord();
06769 if (type != 'T' || id > _cur_parameter->max_value) {
06770 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
06771 if (!SkipUnknownInfo(buf, type)) return false;
06772 type = buf->ReadByte();
06773 continue;
06774 }
06775
06776 byte langid = buf->ReadByte();
06777 const char *name_string = buf->ReadString();
06778
06779 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
06780 if (val_name != _cur_parameter->value_names.End()) {
06781 AddGRFTextToList(&val_name->second, langid, _cur_grfconfig->ident.grfid, name_string);
06782 } else {
06783 GRFText *list = NULL;
06784 AddGRFTextToList(&list, langid, _cur_grfconfig->ident.grfid, name_string);
06785 _cur_parameter->value_names.Insert(id, list);
06786 }
06787
06788 type = buf->ReadByte();
06789 }
06790 return true;
06791 }
06792
06793 AllowedSubtags _tags_parameters[] = {
06794 AllowedSubtags('NAME', ChangeGRFParamName),
06795 AllowedSubtags('DESC', ChangeGRFParamDescription),
06796 AllowedSubtags('TYPE', ChangeGRFParamType),
06797 AllowedSubtags('LIMI', ChangeGRFParamLimits),
06798 AllowedSubtags('MASK', ChangeGRFParamMask),
06799 AllowedSubtags('VALU', ChangeGRFParamValueNames),
06800 AllowedSubtags('DFLT', ChangeGRFParamDefault),
06801 AllowedSubtags()
06802 };
06803
06810 static bool HandleParameterInfo(ByteReader *buf)
06811 {
06812 byte type = buf->ReadByte();
06813 while (type != 0) {
06814 uint32 id = buf->ReadDWord();
06815 if (type != 'C' || id >= _cur_grfconfig->num_valid_params) {
06816 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
06817 if (!SkipUnknownInfo(buf, type)) return false;
06818 type = buf->ReadByte();
06819 continue;
06820 }
06821
06822 if (id >= _cur_grfconfig->param_info.Length()) {
06823 uint num_to_add = id - _cur_grfconfig->param_info.Length() + 1;
06824 GRFParameterInfo **newdata = _cur_grfconfig->param_info.Append(num_to_add);
06825 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
06826 }
06827 if (_cur_grfconfig->param_info[id] == NULL) {
06828 _cur_grfconfig->param_info[id] = new GRFParameterInfo(id);
06829 }
06830 _cur_parameter = _cur_grfconfig->param_info[id];
06831
06832 if (!HandleNodes(buf, _tags_parameters)) return false;
06833 type = buf->ReadByte();
06834 }
06835 return true;
06836 }
06837
06838 AllowedSubtags _tags_info[] = {
06839 AllowedSubtags('NAME', ChangeGRFName),
06840 AllowedSubtags('DESC', ChangeGRFDescription),
06841 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
06842 AllowedSubtags('PALS', ChangeGRFPalette),
06843 AllowedSubtags('VRSN', ChangeGRFVersion),
06844 AllowedSubtags('MINV', ChangeGRFMinVersion),
06845 AllowedSubtags('PARA', HandleParameterInfo),
06846 AllowedSubtags()
06847 };
06848
06849 AllowedSubtags _tags_root[] = {
06850 AllowedSubtags('INFO', _tags_info),
06851 AllowedSubtags()
06852 };
06853
06854
06859 static bool SkipUnknownInfo(ByteReader *buf, byte type)
06860 {
06861
06862 switch (type) {
06863 case 'C': {
06864 byte new_type = buf->ReadByte();
06865 while (new_type != 0) {
06866 buf->ReadDWord();
06867 if (!SkipUnknownInfo(buf, new_type)) return false;
06868 new_type = buf->ReadByte();
06869 }
06870 break;
06871 }
06872
06873 case 'T':
06874 buf->ReadByte();
06875 buf->ReadString();
06876 break;
06877
06878 case 'B': {
06879 uint16 size = buf->ReadWord();
06880 buf->Skip(size);
06881 break;
06882 }
06883
06884 default:
06885 return false;
06886 }
06887
06888 return true;
06889 }
06890
06891 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
06892 {
06893 uint i = 0;
06894 AllowedSubtags *tag;
06895 while ((tag = &subtags[i++])->type != 0) {
06896 if (tag->id != BSWAP32(id) || tag->type != type) continue;
06897 switch (type) {
06898 default: NOT_REACHED();
06899
06900 case 'T': {
06901 byte langid = buf->ReadByte();
06902 return tag->handler.text(langid, buf->ReadString());
06903 }
06904
06905 case 'B': {
06906 size_t len = buf->ReadWord();
06907 if (buf->Remaining() < len) return false;
06908 return tag->handler.data(len, buf);
06909 }
06910
06911 case 'C': {
06912 if (tag->handler.call_handler) {
06913 return tag->handler.u.branch(buf);
06914 }
06915 return HandleNodes(buf, tag->handler.u.subtags);
06916 }
06917 }
06918 }
06919 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
06920 return SkipUnknownInfo(buf, type);
06921 }
06922
06923 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
06924 {
06925 byte type = buf->ReadByte();
06926 while (type != 0) {
06927 uint32 id = buf->ReadDWord();
06928 if (!HandleNode(type, id, buf, subtags)) return false;
06929 type = buf->ReadByte();
06930 }
06931 return true;
06932 }
06933
06934
06935 static void StaticGRFInfo(ByteReader *buf)
06936 {
06937
06938 HandleNodes(buf, _tags_root);
06939 }
06940
06941
06942 static void GRFDataBlock(ByteReader *buf)
06943 {
06944
06945
06946 if (_grf_data_blocks == 0) {
06947 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
06948 return;
06949 }
06950
06951 uint8 name_len = buf->ReadByte();
06952 const char *name = reinterpret_cast<const char *>(buf->Data());
06953 buf->Skip(name_len);
06954
06955
06956 if (buf->ReadByte() != 0) {
06957 grfmsg(2, "GRFDataBlock: Name not properly terminated");
06958 return;
06959 }
06960
06961 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
06962
06963 _grf_data_blocks--;
06964
06965 switch (_grf_data_type) {
06966 case GDT_SOUND: LoadGRFSound(buf); break;
06967 default: NOT_REACHED();
06968 }
06969 }
06970
06971
06972
06973 static void GRFUnsafe(ByteReader *buf)
06974 {
06975 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06976
06977
06978 _skip_sprites = -1;
06979 }
06980
06981
06982 static void InitializeGRFSpecial()
06983 {
06984 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
06985 | (1 << 0x0D)
06986 | (1 << 0x0E)
06987 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
06988 | (0 << 0x10)
06989 | (1 << 0x12)
06990 | (1 << 0x13)
06991 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
06992 | (1 << 0x1B)
06993 | (1 << 0x1D)
06994 | (1 << 0x1E);
06995
06996 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
06997 | (1 << 0x08)
06998 | (1 << 0x09)
06999 | (0 << 0x0B)
07000 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
07001 | (1 << 0x12)
07002 | (1 << 0x13)
07003 | (1 << 0x14)
07004 | (1 << 0x16)
07005 | (1 << 0x17)
07006 | (1 << 0x18)
07007 | (1 << 0x19)
07008 | (1 << 0x1A)
07009 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
07010 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07011
07012 _ttdpatch_flags[2] = (1 << 0x01)
07013 | (1 << 0x03)
07014 | (1 << 0x0A)
07015 | (0 << 0x0B)
07016 | (0 << 0x0C)
07017 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07018 | (1 << 0x0E)
07019 | (1 << 0x0F)
07020 | (0 << 0x10)
07021 | (0 << 0x11)
07022 | (1 << 0x12)
07023 | (1 << 0x13)
07024 | (1 << 0x14)
07025 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07026 | (1 << 0x16)
07027 | (1 << 0x17)
07028 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07029 | (1 << 0x19)
07030 | (1 << 0x1A)
07031 | (1 << 0x1B)
07032 | (1 << 0x1C)
07033 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07034 | (1 << 0x1E)
07035 | (0 << 0x1F);
07036
07037 _ttdpatch_flags[3] = (0 << 0x00)
07038 | (1 << 0x01)
07039 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07040 | (1 << 0x03)
07041 | (0 << 0x04)
07042 | (1 << 0x05)
07043 | (1 << 0x06)
07044 | (1 << 0x07)
07045 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07046 | (0 << 0x09)
07047 | (0 << 0x0A)
07048 | (1 << 0x0B)
07049 | (1 << 0x0C)
07050 | (1 << 0x0D)
07051 | (1 << 0x0E)
07052 | (1 << 0x0F)
07053 | (1 << 0x10)
07054 | (1 << 0x11)
07055 | (1 << 0x12)
07056 | (0 << 0x13)
07057 | (1 << 0x14)
07058 | (0 << 0x15)
07059 | (1 << 0x16)
07060 | (1 << 0x17)
07061 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07062 | (1 << 0x1E)
07063 | (1 << 0x1F);
07064 }
07065
07066 static void ResetCustomStations()
07067 {
07068 const GRFFile * const *end = _grf_files.End();
07069 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07070 StationSpec **&stations = (*file)->stations;
07071 if (stations == NULL) continue;
07072 for (uint i = 0; i < MAX_STATIONS; i++) {
07073 if (stations[i] == NULL) continue;
07074 StationSpec *statspec = stations[i];
07075
07076 for (uint t = 0; t < statspec->tiles; t++) {
07077 free((void*)statspec->renderdata[t].seq);
07078 }
07079 free(statspec->renderdata);
07080
07081
07082 if (!statspec->copied_layouts) {
07083 for (uint l = 0; l < statspec->lengths; l++) {
07084 for (uint p = 0; p < statspec->platforms[l]; p++) {
07085 free(statspec->layouts[l][p]);
07086 }
07087 free(statspec->layouts[l]);
07088 }
07089 free(statspec->layouts);
07090 free(statspec->platforms);
07091 }
07092
07093
07094 free(statspec);
07095 }
07096
07097
07098 free(stations);
07099 stations = NULL;
07100 }
07101 }
07102
07103 static void ResetCustomHouses()
07104 {
07105 const GRFFile * const *end = _grf_files.End();
07106 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07107 HouseSpec **&housespec = (*file)->housespec;
07108 if (housespec == NULL) continue;
07109 for (uint i = 0; i < HOUSE_MAX; i++) {
07110 free(housespec[i]);
07111 }
07112
07113 free(housespec);
07114 housespec = NULL;
07115 }
07116 }
07117
07118 static void ResetCustomAirports()
07119 {
07120 const GRFFile * const *end = _grf_files.End();
07121 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07122 AirportSpec **aslist = (*file)->airportspec;
07123 if (aslist != NULL) {
07124 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07125 AirportSpec *as = aslist[i];
07126
07127 if (as != NULL) {
07128
07129 for (int j = 0; j < as->num_table; j++) {
07130
07131 free((void*)as->table[j]);
07132 }
07133 free((void*)as->table);
07134
07135 free(as);
07136 }
07137 }
07138 free(aslist);
07139 (*file)->airportspec = NULL;
07140 }
07141
07142 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07143 if (airporttilespec != NULL) {
07144 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07145 free(airporttilespec[i]);
07146 }
07147 free(airporttilespec);
07148 airporttilespec = NULL;
07149 }
07150 }
07151 }
07152
07153 static void ResetCustomIndustries()
07154 {
07155 const GRFFile * const *end = _grf_files.End();
07156 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07157 IndustrySpec **&industryspec = (*file)->industryspec;
07158 IndustryTileSpec **&indtspec = (*file)->indtspec;
07159
07160
07161
07162 if (industryspec != NULL) {
07163 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07164 IndustrySpec *ind = industryspec[i];
07165 if (ind == NULL) continue;
07166
07167
07168 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07169 free((void*)ind->random_sounds);
07170 }
07171
07172
07173 CleanIndustryTileTable(ind);
07174
07175 free(ind);
07176 }
07177
07178 free(industryspec);
07179 industryspec = NULL;
07180 }
07181
07182 if (indtspec == NULL) continue;
07183 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07184 free(indtspec[i]);
07185 }
07186
07187 free(indtspec);
07188 indtspec = NULL;
07189 }
07190 }
07191
07192 static void ResetCustomObjects()
07193 {
07194 const GRFFile * const *end = _grf_files.End();
07195 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07196 ObjectSpec **&objectspec = (*file)->objectspec;
07197 if (objectspec == NULL) continue;
07198 for (uint i = 0; i < NUM_OBJECTS; i++) {
07199 free(objectspec[i]);
07200 }
07201
07202 free(objectspec);
07203 objectspec = NULL;
07204 }
07205 }
07206
07207
07208 static void ResetNewGRF()
07209 {
07210 const GRFFile * const *end = _grf_files.End();
07211 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07212 GRFFile *f = *file;
07213 free(f->filename);
07214 free(f->cargo_list);
07215 free(f->railtype_list);
07216 delete [] f->language_map;
07217 free(f);
07218 }
07219
07220 _grf_files.Clear();
07221 _cur_grffile = NULL;
07222 }
07223
07224 static void ResetNewGRFErrors()
07225 {
07226 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07227 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07228 delete c->error;
07229 c->error = NULL;
07230 }
07231 }
07232 }
07233
07238 void ResetNewGRFData()
07239 {
07240 CleanUpStrings();
07241 CleanUpGRFTownNames();
07242
07243
07244 SetupEngines();
07245
07246
07247 ResetBridges();
07248
07249
07250 ResetRailTypes();
07251
07252
07253 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07254
07255
07256 Engine *e;
07257 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07258 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07259 }
07260
07261
07262 memset(&_grm_engines, 0, sizeof(_grm_engines));
07263 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
07264
07265
07266 ResetGenericCallbacks();
07267
07268
07269 ResetPriceBaseMultipliers();
07270
07271
07272 ResetCurrencies();
07273
07274
07275 ResetCustomHouses();
07276 ResetHouses();
07277
07278
07279 ResetCustomIndustries();
07280 ResetIndustries();
07281
07282
07283 ObjectClass::Reset();
07284 ResetCustomObjects();
07285 ResetObjects();
07286
07287
07288 StationClass::Reset();
07289 ResetCustomStations();
07290
07291
07292 AirportClass::Reset();
07293 ResetCustomAirports();
07294 AirportSpec::ResetAirports();
07295 AirportTileSpec::ResetAirportTiles();
07296
07297
07298 memset(_water_feature, 0, sizeof(_water_feature));
07299
07300
07301 ClearSnowLine();
07302
07303
07304 ResetNewGRF();
07305
07306
07307 ResetNewGRFErrors();
07308
07309
07310 SetupCargoForClimate(_settings_game.game_creation.landscape);
07311
07312
07313 _misc_grf_features = 0;
07314
07315 _loaded_newgrf_features.has_2CC = false;
07316 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07317 _loaded_newgrf_features.has_newhouses = false;
07318 _loaded_newgrf_features.has_newindustries = false;
07319 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07320
07321
07322 _grf_id_overrides.clear();
07323
07324 InitializeSoundPool();
07325 _spritegroup_pool.CleanPool();
07326 }
07327
07328 static void BuildCargoTranslationMap()
07329 {
07330 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
07331
07332 for (CargoID c = 0; c < NUM_CARGO; c++) {
07333 const CargoSpec *cs = CargoSpec::Get(c);
07334 if (!cs->IsValid()) continue;
07335
07336 if (_cur_grffile->cargo_max == 0) {
07337
07338 _cur_grffile->cargo_map[c] = cs->bitnum;
07339 } else {
07340
07341 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
07342 if (cs->label == _cur_grffile->cargo_list[i]) {
07343 _cur_grffile->cargo_map[c] = i;
07344 break;
07345 }
07346 }
07347 }
07348 }
07349 }
07350
07351 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
07352 {
07353 GRFFile *newfile = GetFileByFilename(config->filename);
07354 if (newfile != NULL) {
07355
07356 newfile->sprite_offset = sprite_offset;
07357 _cur_grffile = newfile;
07358 return;
07359 }
07360
07361 newfile = CallocT<GRFFile>(1);
07362
07363 newfile->filename = strdup(config->filename);
07364 newfile->sprite_offset = sprite_offset;
07365 newfile->grfid = config->ident.grfid;
07366
07367
07368 newfile->traininfo_vehicle_pitch = 0;
07369 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
07370
07371
07372 for (Price i = PR_BEGIN; i < PR_END; i++) {
07373 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
07374 }
07375
07376
07377 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
07378 newfile->railtype_map[0] = RAILTYPE_RAIL;
07379 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
07380 newfile->railtype_map[2] = RAILTYPE_MONO;
07381 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
07382
07383
07384
07385 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
07386 memset(newfile->param, 0, sizeof(newfile->param));
07387
07388 assert(config->num_params <= lengthof(config->param));
07389 newfile->param_end = config->num_params;
07390 if (newfile->param_end > 0) {
07391 MemCpyT(newfile->param, config->param, newfile->param_end);
07392 }
07393
07394 *_grf_files.Append() = _cur_grffile = newfile;
07395 }
07396
07397
07402 static const CargoLabel _default_refitmasks_rail[] = {
07403 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
07404 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
07405 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07406 'PLST', 'FZDR',
07407 0 };
07408
07409 static const CargoLabel _default_refitmasks_road[] = {
07410 0 };
07411
07412 static const CargoLabel _default_refitmasks_ships[] = {
07413 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
07414 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
07415 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07416 'PLST', 'FZDR',
07417 0 };
07418
07419 static const CargoLabel _default_refitmasks_aircraft[] = {
07420 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
07421 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
07422 0 };
07423
07424 static const CargoLabel * const _default_refitmasks[] = {
07425 _default_refitmasks_rail,
07426 _default_refitmasks_road,
07427 _default_refitmasks_ships,
07428 _default_refitmasks_aircraft,
07429 };
07430
07431
07435 static void CalculateRefitMasks()
07436 {
07437 Engine *e;
07438
07439 FOR_ALL_ENGINES(e) {
07440 EngineID engine = e->index;
07441 EngineInfo *ei = &e->info;
07442 uint32 mask = 0;
07443 uint32 not_mask = 0;
07444 uint32 xor_mask = 0;
07445
07446
07447 if (_gted[engine].refitmask_valid) {
07448 if (ei->refit_mask != 0) {
07449 const GRFFile *file = _gted[engine].refitmask_grf;
07450 if (file == NULL) file = e->grf_prop.grffile;
07451 if (file != NULL && file->cargo_max != 0) {
07452
07453 uint num_cargo = min(32, file->cargo_max);
07454 for (uint i = 0; i < num_cargo; i++) {
07455 if (!HasBit(ei->refit_mask, i)) continue;
07456
07457 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
07458 if (c == CT_INVALID) continue;
07459
07460 SetBit(xor_mask, c);
07461 }
07462 } else {
07463
07464 const CargoSpec *cs;
07465 FOR_ALL_CARGOSPECS(cs) {
07466 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
07467 }
07468 }
07469 }
07470
07471 if (_gted[engine].cargo_allowed != 0) {
07472
07473 const CargoSpec *cs;
07474 FOR_ALL_CARGOSPECS(cs) {
07475 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
07476 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
07477 }
07478 }
07479 } else {
07480
07481 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
07482 const CargoLabel *cl = _default_refitmasks[e->type];
07483 for (uint i = 0;; i++) {
07484 if (cl[i] == 0) break;
07485
07486 CargoID cargo = GetCargoIDByLabel(cl[i]);
07487 if (cargo == CT_INVALID) continue;
07488
07489 SetBit(xor_mask, cargo);
07490 }
07491 }
07492 }
07493
07494 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
07495
07496
07497
07498 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
07499 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
07500
07501
07502 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
07503 }
07504 }
07505
07507 static void FinaliseEngineArray()
07508 {
07509 Engine *e;
07510
07511 FOR_ALL_ENGINES(e) {
07512 if (e->grf_prop.grffile == NULL) {
07513 const EngineIDMapping &eid = _engine_mngr[e->index];
07514 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
07515 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
07516 }
07517 }
07518
07519
07520
07521
07522 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->grf_prop.grffile != NULL && is_custom_sprite(e->u.rail.image_index)) {
07523 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
07524 }
07525
07526
07527 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
07528 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
07529 SetBit(_loaded_newgrf_features.used_liveries, ls);
07530
07531
07532 if (e->type == VEH_TRAIN) {
07533 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
07534 switch (ls) {
07535 case LS_STEAM:
07536 case LS_DIESEL:
07537 case LS_ELECTRIC:
07538 case LS_MONORAIL:
07539 case LS_MAGLEV:
07540 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
07541 break;
07542
07543 case LS_DMU:
07544 case LS_EMU:
07545 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
07546 break;
07547
07548 default: NOT_REACHED();
07549 }
07550 }
07551 }
07552 }
07553 }
07554
07556 static void FinaliseCargoArray()
07557 {
07558 for (CargoID c = 0; c < NUM_CARGO; c++) {
07559 CargoSpec *cs = CargoSpec::Get(c);
07560 if (!cs->IsValid()) {
07561 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
07562 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
07563 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
07564 }
07565 }
07566 }
07567
07579 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
07580 {
07581 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
07582 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
07583 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
07584 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
07585 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
07586 hs->enabled = false;
07587 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);
07588 return false;
07589 }
07590
07591
07592
07593
07594 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
07595 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
07596 hs->enabled = false;
07597 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);
07598 return false;
07599 }
07600
07601
07602
07603 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
07604 hs->enabled = false;
07605 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);
07606 return false;
07607 }
07608
07609
07610 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
07611 hs->enabled = false;
07612 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);
07613 return false;
07614 }
07615
07616 return true;
07617 }
07618
07625 static void EnsureEarlyHouse(HouseZones bitmask)
07626 {
07627 Year min_year = MAX_YEAR;
07628
07629 for (int i = 0; i < HOUSE_MAX; i++) {
07630 HouseSpec *hs = HouseSpec::Get(i);
07631 if (hs == NULL || !hs->enabled) continue;
07632 if ((hs->building_availability & bitmask) != bitmask) continue;
07633 if (hs->min_year < min_year) min_year = hs->min_year;
07634 }
07635
07636 if (min_year == 0) return;
07637
07638 for (int i = 0; i < HOUSE_MAX; i++) {
07639 HouseSpec *hs = HouseSpec::Get(i);
07640 if (hs == NULL || !hs->enabled) continue;
07641 if ((hs->building_availability & bitmask) != bitmask) continue;
07642 if (hs->min_year == min_year) hs->min_year = 0;
07643 }
07644 }
07645
07652 static void FinaliseHouseArray()
07653 {
07654
07655
07656
07657
07658
07659
07660
07661
07662
07663 const GRFFile * const *end = _grf_files.End();
07664 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07665 HouseSpec **&housespec = (*file)->housespec;
07666 if (housespec == NULL) continue;
07667
07668 for (int i = 0; i < HOUSE_MAX; i++) {
07669 HouseSpec *hs = housespec[i];
07670
07671 if (hs == NULL) continue;
07672
07673 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
07674 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
07675 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
07676
07677 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
07678
07679 _house_mngr.SetEntitySpec(hs);
07680 }
07681 }
07682
07683 for (int i = 0; i < HOUSE_MAX; i++) {
07684 HouseSpec *hs = HouseSpec::Get(i);
07685 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
07686 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
07687 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
07688
07689
07690
07691 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
07692
07693
07694
07695
07696
07697
07698
07699 hs->building_flags = TILE_NO_FLAG;
07700 }
07701 }
07702
07703 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
07704 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
07705 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
07706 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
07707 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
07708 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
07709
07710 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
07711 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
07712 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
07713 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
07714 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
07715 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
07716 }
07717 }
07718
07724 static void FinaliseIndustriesArray()
07725 {
07726 const GRFFile * const *end = _grf_files.End();
07727 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07728 IndustrySpec **&industryspec = (*file)->industryspec;
07729 IndustryTileSpec **&indtspec = (*file)->indtspec;
07730 if (industryspec != NULL) {
07731 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
07732 IndustrySpec *indsp = industryspec[i];
07733
07734 if (indsp != NULL && indsp->enabled) {
07735 StringID strid;
07736
07737
07738
07739 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
07740 if (strid != STR_UNDEFINED) indsp->name = strid;
07741
07742 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
07743 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
07744
07745 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
07746 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
07747
07748 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
07749 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
07750
07751 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
07752 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
07753
07754 if (indsp->station_name != STR_NULL) {
07755
07756
07757 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
07758 if (strid != STR_UNDEFINED) indsp->station_name = strid;
07759 }
07760
07761 _industry_mngr.SetEntitySpec(indsp);
07762 _loaded_newgrf_features.has_newindustries = true;
07763 }
07764 }
07765 }
07766
07767 if (indtspec != NULL) {
07768 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
07769 IndustryTileSpec *indtsp = indtspec[i];
07770 if (indtsp != NULL) {
07771 _industile_mngr.SetEntitySpec(indtsp);
07772 }
07773 }
07774 }
07775 }
07776
07777 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
07778 IndustrySpec *indsp = &_industry_specs[j];
07779 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
07780 for (uint i = 0; i < 3; i++) {
07781 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
07782 }
07783 }
07784 if (!indsp->enabled) {
07785 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
07786 }
07787 }
07788 }
07789
07795 static void FinaliseObjectsArray()
07796 {
07797 const GRFFile * const *end = _grf_files.End();
07798 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07799 ObjectSpec **&objectspec = (*file)->objectspec;
07800 if (objectspec != NULL) {
07801 for (int i = 0; i < NUM_OBJECTS; i++) {
07802 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
07803 _object_mngr.SetEntitySpec(objectspec[i]);
07804 }
07805 }
07806 }
07807 }
07808 }
07809
07815 static void FinaliseAirportsArray()
07816 {
07817 const GRFFile * const *end = _grf_files.End();
07818 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07819 AirportSpec **&airportspec = (*file)->airportspec;
07820 if (airportspec != NULL) {
07821 for (int i = 0; i < NUM_AIRPORTS; i++) {
07822 if (airportspec[i] != NULL && airportspec[i]->enabled) {
07823 _airport_mngr.SetEntitySpec(airportspec[i]);
07824 }
07825 }
07826 }
07827
07828 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07829 if (airporttilespec != NULL) {
07830 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07831 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
07832 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
07833 }
07834 }
07835 }
07836 }
07837 }
07838
07839
07840
07841
07842
07843
07844
07845 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
07846 {
07847
07848
07849
07850
07851
07852
07853
07854
07855
07856
07857
07858
07859 static const SpecialSpriteHandler handlers[][GLS_END] = {
07860 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
07861 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
07862 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
07863 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
07864 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
07865 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
07866 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
07867 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
07868 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
07869 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
07870 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
07871 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
07872 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
07873 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
07874 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
07875 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
07876 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
07877 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
07878 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
07879 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
07880 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
07881 };
07882
07883 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line);
07884
07885 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
07886 if (it == _grf_line_to_action6_sprite_override.end()) {
07887
07888
07889 FioReadBlock(buf, num);
07890 } else {
07891
07892 buf = _grf_line_to_action6_sprite_override[location];
07893 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
07894
07895
07896 FioSeekTo(num, SEEK_CUR);
07897 }
07898
07899 ByteReader br(buf, buf + num);
07900 ByteReader *bufp = &br;
07901
07902 try {
07903 byte action = bufp->ReadByte();
07904
07905 if (action == 0xFF) {
07906 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
07907 GRFDataBlock(bufp);
07908 } else if (action == 0xFE) {
07909 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
07910 GRFImportBlock(bufp);
07911 } else if (action >= lengthof(handlers)) {
07912 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
07913 } else if (handlers[action][stage] == NULL) {
07914 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
07915 } else {
07916 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
07917 handlers[action][stage](bufp);
07918 }
07919 } catch (...) {
07920 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
07921 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
07922 }
07923 }
07924
07925
07926 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
07927 {
07928 const char *filename = config->filename;
07929 uint16 num;
07930
07931
07932
07933
07934
07935
07936
07937
07938
07939
07940 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
07941 _cur_grffile = GetFileByFilename(filename);
07942 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
07943 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
07944 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
07945 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
07946 }
07947
07948 if (file_index > LAST_GRF_SLOT) {
07949 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
07950 config->status = GCS_DISABLED;
07951 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
07952 return;
07953 }
07954
07955 FioOpenFile(file_index, filename);
07956 _file_index = file_index;
07957 _palette_remap_grf[_file_index] = ((config->palette & GRFP_USE_MASK) != (_use_palette == PAL_WINDOWS));
07958
07959 _cur_grfconfig = config;
07960
07961 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
07962
07963
07964
07965
07966 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
07967 FioReadDword();
07968 } else {
07969 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
07970 return;
07971 }
07972
07973 _skip_sprites = 0;
07974 _nfo_line = 0;
07975
07976 ReusableBuffer<byte> buf;
07977
07978 while ((num = FioReadWord()) != 0) {
07979 byte type = FioReadByte();
07980 _nfo_line++;
07981
07982 if (type == 0xFF) {
07983 if (_skip_sprites == 0) {
07984 DecodeSpecialSprite(buf.Allocate(num), num, stage);
07985
07986
07987 if (_skip_sprites == -1) break;
07988
07989 continue;
07990 } else {
07991 FioSkipBytes(num);
07992 }
07993 } else {
07994 if (_skip_sprites == 0) {
07995 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
07996 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
07997 break;
07998 }
07999
08000 FioSkipBytes(7);
08001 SkipSpriteData(type, num - 8);
08002 }
08003
08004 if (_skip_sprites > 0) _skip_sprites--;
08005 }
08006 }
08007
08015 static void ActivateOldShore()
08016 {
08017
08018
08019 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08020
08021 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08022 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08023 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08024 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08025 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08026 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08027 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08028 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08029 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08030 }
08031
08032 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08033 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08034 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08035 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08036 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08037 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08038 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08039 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08040 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08041
08042
08043
08044 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08045 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08046 }
08047 }
08048
08052 static void FinalisePriceBaseMultipliers()
08053 {
08054 extern const PriceBaseSpec _price_base_specs[];
08055 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08056
08057
08058 int num_grfs = _grf_files.Length();
08059 int *grf_overrides = AllocaM(int, num_grfs);
08060 for (int i = 0; i < num_grfs; i++) {
08061 grf_overrides[i] = -1;
08062
08063 GRFFile *source = _grf_files[i];
08064 uint32 override = _grf_id_overrides[source->grfid];
08065 if (override == 0) continue;
08066
08067 GRFFile *dest = GetFileByGRFID(override);
08068 if (dest == NULL) continue;
08069
08070 grf_overrides[i] = _grf_files.FindIndex(dest);
08071 assert(grf_overrides[i] >= 0);
08072 }
08073
08074
08075 for (int i = 0; i < num_grfs; i++) {
08076 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08077 GRFFile *source = _grf_files[i];
08078 GRFFile *dest = _grf_files[grf_overrides[i]];
08079
08080 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08081 source->grf_features |= features;
08082 dest->grf_features |= features;
08083
08084 for (Price p = PR_BEGIN; p < PR_END; p++) {
08085
08086 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08087 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08088 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08089 }
08090 }
08091
08092
08093 for (int i = num_grfs - 1; i >= 0; i--) {
08094 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08095 GRFFile *source = _grf_files[i];
08096 GRFFile *dest = _grf_files[grf_overrides[i]];
08097
08098 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08099 source->grf_features |= features;
08100 dest->grf_features |= features;
08101
08102 for (Price p = PR_BEGIN; p < PR_END; p++) {
08103
08104 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08105 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08106 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08107 }
08108 }
08109
08110
08111 for (int i = 0; i < num_grfs; i++) {
08112 if (grf_overrides[i] < 0) continue;
08113 GRFFile *source = _grf_files[i];
08114 GRFFile *dest = _grf_files[grf_overrides[i]];
08115
08116 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08117 source->grf_features |= features;
08118 dest->grf_features |= features;
08119
08120 for (Price p = PR_BEGIN; p < PR_END; p++) {
08121 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08122 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08123 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08124 }
08125 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08126 }
08127 }
08128
08129
08130 const GRFFile * const *end = _grf_files.End();
08131 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08132 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08133 for (Price p = PR_BEGIN; p < PR_END; p++) {
08134 Price fallback_price = _price_base_specs[p].fallback_price;
08135 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08136
08137
08138 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08139 }
08140 }
08141 }
08142
08143
08144 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08145 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08146 for (Price p = PR_BEGIN; p < PR_END; p++) {
08147 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08148
08149 price_base_multipliers[p] = 0;
08150 } else {
08151 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08152
08153
08154 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08155 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08156 price_base_multipliers[p] = 0;
08157 } else {
08158 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08159 }
08160 }
08161 }
08162 }
08163 }
08164
08165 void InitDepotWindowBlockSizes();
08166
08167 extern void InitGRFTownGeneratorNames();
08168
08169 static void AfterLoadGRFs()
08170 {
08171 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08172 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08173 }
08174 _string_to_grf_mapping.clear();
08175
08176
08177 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08178 free((*it).second);
08179 }
08180 _grf_line_to_action6_sprite_override.clear();
08181
08182
08183 FinaliseCargoArray();
08184
08185
08186 CalculateRefitMasks();
08187
08188
08189 FinaliseEngineArray();
08190
08191
08192 InitDepotWindowBlockSizes();
08193
08194
08195 FinaliseHouseArray();
08196
08197
08198 FinaliseIndustriesArray();
08199
08200
08201 FinaliseObjectsArray();
08202
08203 InitializeSortedCargoSpecs();
08204
08205
08206 SortIndustryTypes();
08207
08208
08209 BuildIndustriesLegend();
08210
08211
08212 FinaliseAirportsArray();
08213 BindAirportSpecs();
08214
08215
08216 InitGRFTownGeneratorNames();
08217
08218
08219 CommitVehicleListOrderChanges();
08220
08221
08222 ActivateOldShore();
08223
08224
08225 InitRailTypes();
08226
08227 Engine *e;
08228 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
08229 if (_gted[e->index].rv_max_speed != 0) {
08230
08231 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
08232 }
08233 }
08234
08235 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
08236 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
08237 if (railtype == INVALID_RAILTYPE) {
08238
08239 e->info.climates = 0x80;
08240 } else {
08241 e->u.rail.railtype = railtype;
08242 }
08243 }
08244
08245 SetYearEngineAgingStops();
08246
08247 FinalisePriceBaseMultipliers();
08248
08249
08250 free(_gted);
08251 _grm_sprites.clear();
08252 }
08253
08254 void LoadNewGRF(uint load_index, uint file_index)
08255 {
08256
08257
08258
08259
08260 Date date = _date;
08261 Year year = _cur_year;
08262 DateFract date_fract = _date_fract;
08263 uint16 tick_counter = _tick_counter;
08264 byte display_opt = _display_opt;
08265
08266 if (_networking) {
08267 _cur_year = _settings_game.game_creation.starting_year;
08268 _date = ConvertYMDToDate(_cur_year, 0, 1);
08269 _date_fract = 0;
08270 _tick_counter = 0;
08271 _display_opt = 0;
08272 }
08273
08274 InitializeGRFSpecial();
08275
08276 ResetNewGRFData();
08277
08278
08279
08280
08281
08282
08283
08284
08285 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08286 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
08287 }
08288
08289 _cur_spriteid = load_index;
08290
08291
08292
08293
08294 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
08295
08296
08297 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08298 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
08299 }
08300
08301 uint slot = file_index;
08302
08303 _cur_stage = stage;
08304 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08305 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
08306 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
08307
08308 if (!FioCheckFileExists(c->filename)) {
08309 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
08310 c->status = GCS_NOT_FOUND;
08311 continue;
08312 }
08313
08314 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
08315 LoadNewGRFFile(c, slot++, stage);
08316 if (stage == GLS_RESERVE) {
08317 SetBit(c->flags, GCF_RESERVED);
08318 } else if (stage == GLS_ACTIVATION) {
08319 ClrBit(c->flags, GCF_RESERVED);
08320 assert(GetFileByGRFID(c->ident.grfid) == _cur_grffile);
08321 ClearTemporaryNewGRFData(_cur_grffile);
08322 BuildCargoTranslationMap();
08323 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
08324 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
08325
08326 ClearTemporaryNewGRFData(_cur_grffile);
08327 }
08328 }
08329 }
08330
08331
08332 AfterLoadGRFs();
08333
08334
08335 _cur_year = year;
08336 _date = date;
08337 _date_fract = date_fract;
08338 _tick_counter = tick_counter;
08339 _display_opt = display_opt;
08340 }
08341
08342 bool HasGrfMiscBit(GrfMiscBit bit)
08343 {
08344 return HasBit(_misc_grf_features, bit);
08345 }