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 CanalProperties *cp = &_cur_grffile->canal_local_properties[id + i];
01439
01440 switch (prop) {
01441 case 0x08:
01442 cp->callback_mask = buf->ReadByte();
01443 break;
01444
01445 case 0x09:
01446 cp->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
01682 _loaded_newgrf_features.has_newhouses = true;
01683 break;
01684 }
01685
01686 case 0x09:
01687 housespec->building_flags = (BuildingFlags)buf->ReadByte();
01688 break;
01689
01690 case 0x0A: {
01691 uint16 years = buf->ReadWord();
01692 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
01693 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
01694 break;
01695 }
01696
01697 case 0x0B:
01698 housespec->population = buf->ReadByte();
01699 break;
01700
01701 case 0x0C:
01702 housespec->mail_generation = buf->ReadByte();
01703 break;
01704
01705 case 0x0D:
01706 case 0x0E:
01707 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
01708 break;
01709
01710 case 0x0F: {
01711 int8 goods = buf->ReadByte();
01712
01713
01714
01715 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
01716 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
01717
01718
01719 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
01720
01721 housespec->accepts_cargo[2] = cid;
01722 housespec->cargo_acceptance[2] = abs(goods);
01723 break;
01724 }
01725
01726 case 0x10:
01727 housespec->remove_rating_decrease = buf->ReadWord();
01728 break;
01729
01730 case 0x11:
01731 housespec->removal_cost = buf->ReadByte();
01732 break;
01733
01734 case 0x12:
01735 housespec->building_name = buf->ReadWord();
01736 _string_to_grf_mapping[&housespec->building_name] = _cur_grffile->grfid;
01737 break;
01738
01739 case 0x13:
01740 housespec->building_availability = (HouseZones)buf->ReadWord();
01741 break;
01742
01743 case 0x14:
01744 housespec->callback_mask |= buf->ReadByte();
01745 break;
01746
01747 case 0x15: {
01748 byte override = buf->ReadByte();
01749
01750
01751 if (override >= NEW_HOUSE_OFFSET) {
01752 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
01753 continue;
01754 }
01755
01756 _house_mngr.Add(hid + i, _cur_grffile->grfid, override);
01757 break;
01758 }
01759
01760 case 0x16:
01761 housespec->processing_time = min(buf->ReadByte(), 63);
01762 break;
01763
01764 case 0x17:
01765 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
01766 break;
01767
01768 case 0x18:
01769 housespec->probability = buf->ReadByte();
01770 break;
01771
01772 case 0x19:
01773 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
01774 break;
01775
01776 case 0x1A:
01777 housespec->animation.frames = buf->ReadByte();
01778 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
01779 SB(housespec->animation.frames, 7, 1, 0);
01780 break;
01781
01782 case 0x1B:
01783 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
01784 break;
01785
01786 case 0x1C:
01787 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur_grffile->grfid);
01788 break;
01789
01790 case 0x1D:
01791 housespec->callback_mask |= (buf->ReadByte() << 8);
01792 break;
01793
01794 case 0x1E: {
01795 uint32 cargotypes = buf->ReadDWord();
01796
01797
01798 if (cargotypes == 0xFFFFFFFF) break;
01799
01800 for (uint j = 0; j < 3; j++) {
01801
01802 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
01803 CargoID cargo = GetCargoTranslation(cargo_part, _cur_grffile);
01804
01805 if (cargo == CT_INVALID) {
01806
01807 housespec->cargo_acceptance[j] = 0;
01808 } else {
01809 housespec->accepts_cargo[j] = cargo;
01810 }
01811 }
01812 break;
01813 }
01814
01815 case 0x1F:
01816 housespec->minimum_life = buf->ReadByte();
01817 break;
01818
01819 case 0x20: {
01820 byte count = buf->ReadByte();
01821 for (byte j = 0; j < count; j++) buf->ReadByte();
01822 ret = CIR_UNHANDLED;
01823 break;
01824 }
01825
01826 case 0x21:
01827 housespec->min_year = buf->ReadWord();
01828 break;
01829
01830 case 0x22:
01831 housespec->max_year = buf->ReadWord();
01832 break;
01833
01834 default:
01835 ret = CIR_UNKNOWN;
01836 break;
01837 }
01838 }
01839
01840 return ret;
01841 }
01842
01849 const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
01850 {
01851
01852 const GRFFile *grffile = GetFileByGRFID(grfid);
01853 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
01854 }
01855
01856 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
01857 {
01858 ChangeInfoResult ret = CIR_SUCCESS;
01859
01860 for (int i = 0; i < numinfo; i++) {
01861 switch (prop) {
01862 case 0x08: {
01863 int factor = buf->ReadByte();
01864 uint price = gvid + i;
01865
01866 if (price < PR_END) {
01867 _cur_grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
01868 } else {
01869 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
01870 }
01871 break;
01872 }
01873
01874 case 0x09:
01875
01876
01877 buf->Skip(4);
01878 break;
01879
01880 case 0x0A: {
01881 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01882 StringID newone = GetGRFStringID(_cur_grffile->grfid, buf->ReadWord());
01883
01884 if ((newone != STR_UNDEFINED) && (curidx < NUM_CURRENCY)) {
01885 _currency_specs[curidx].name = newone;
01886 }
01887 break;
01888 }
01889
01890 case 0x0B: {
01891 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01892 uint32 rate = buf->ReadDWord();
01893
01894 if (curidx < NUM_CURRENCY) {
01895
01896
01897
01898 _currency_specs[curidx].rate = rate / 1000;
01899 } else {
01900 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
01901 }
01902 break;
01903 }
01904
01905 case 0x0C: {
01906 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01907 uint16 options = buf->ReadWord();
01908
01909 if (curidx < NUM_CURRENCY) {
01910 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
01911 _currency_specs[curidx].separator[1] = '\0';
01912
01913
01914 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
01915 } else {
01916 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
01917 }
01918 break;
01919 }
01920
01921 case 0x0D: {
01922 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01923 uint32 tempfix = buf->ReadDWord();
01924
01925 if (curidx < NUM_CURRENCY) {
01926 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
01927 _currency_specs[curidx].prefix[4] = 0;
01928 } else {
01929 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01930 }
01931 break;
01932 }
01933
01934 case 0x0E: {
01935 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01936 uint32 tempfix = buf->ReadDWord();
01937
01938 if (curidx < NUM_CURRENCY) {
01939 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
01940 _currency_specs[curidx].suffix[4] = 0;
01941 } else {
01942 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
01943 }
01944 break;
01945 }
01946
01947 case 0x0F: {
01948 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
01949 Year year_euro = buf->ReadWord();
01950
01951 if (curidx < NUM_CURRENCY) {
01952 _currency_specs[curidx].to_euro = year_euro;
01953 } else {
01954 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
01955 }
01956 break;
01957 }
01958
01959 case 0x10:
01960 if (numinfo > 1 || IsSnowLineSet()) {
01961 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
01962 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
01963 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
01964 } else {
01965 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
01966
01967 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
01968 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
01969 table[i][j] = buf->ReadByte();
01970 }
01971 }
01972 SetSnowLine(table);
01973 }
01974 break;
01975
01976 case 0x11:
01977
01978
01979 buf->Skip(8);
01980 break;
01981
01982 case 0x12:
01983
01984
01985 buf->Skip(4);
01986 break;
01987
01988 case 0x13:
01989 case 0x14:
01990 case 0x15: {
01991 uint curidx = gvid + i;
01992 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
01993 if (lang == NULL) {
01994 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
01995
01996 while (buf->ReadByte() != 0) {
01997 buf->ReadString();
01998 }
01999 break;
02000 }
02001
02002 if (_cur_grffile->language_map == NULL) _cur_grffile->language_map = new LanguageMap[MAX_LANG];
02003
02004 if (prop == 0x15) {
02005 uint plural_form = buf->ReadByte();
02006 if (plural_form >= LANGUAGE_MAX_PLURAL) {
02007 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
02008 } else {
02009 _cur_grffile->language_map[curidx].plural_form = plural_form;
02010 }
02011 break;
02012 }
02013
02014 byte newgrf_id = buf->ReadByte();
02015 while (newgrf_id != 0) {
02016 const char *name = buf->ReadString();
02017
02018
02019
02020
02021
02022 WChar c;
02023 size_t len = Utf8Decode(&c, name);
02024 if (c == NFO_UTF8_IDENTIFIER) name += len;
02025
02026 LanguageMap::Mapping map;
02027 map.newgrf_id = newgrf_id;
02028 if (prop == 0x13) {
02029 map.openttd_id = lang->GetGenderIndex(name);
02030 if (map.openttd_id >= MAX_NUM_GENDERS) {
02031 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
02032 } else {
02033 *_cur_grffile->language_map[curidx].gender_map.Append() = map;
02034 }
02035 } else {
02036 map.openttd_id = lang->GetCaseIndex(name);
02037 if (map.openttd_id >= MAX_NUM_CASES) {
02038 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
02039 } else {
02040 *_cur_grffile->language_map[curidx].case_map.Append() = map;
02041 }
02042 }
02043 newgrf_id = buf->ReadByte();
02044 }
02045 break;
02046 }
02047
02048 default:
02049 ret = CIR_UNKNOWN;
02050 break;
02051 }
02052 }
02053
02054 return ret;
02055 }
02056
02057 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
02058 {
02059 ChangeInfoResult ret = CIR_SUCCESS;
02060
02061 for (int i = 0; i < numinfo; i++) {
02062 switch (prop) {
02063 case 0x08:
02064 case 0x15:
02065 buf->ReadByte();
02066 break;
02067
02068 case 0x09: {
02069 if (i == 0) {
02070 if (gvid != 0) {
02071 grfmsg(1, "ReserveChangeInfo: Cargo translation table must start at zero");
02072 return CIR_INVALID_ID;
02073 }
02074
02075 free(_cur_grffile->cargo_list);
02076 _cur_grffile->cargo_max = numinfo;
02077 _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
02078 }
02079
02080 CargoLabel cl = buf->ReadDWord();
02081 _cur_grffile->cargo_list[i] = BSWAP32(cl);
02082 break;
02083 }
02084
02085 case 0x0A:
02086 case 0x0C:
02087 case 0x0F:
02088 buf->ReadWord();
02089 break;
02090
02091 case 0x0B:
02092 case 0x0D:
02093 case 0x0E:
02094 buf->ReadDWord();
02095 break;
02096
02097 case 0x10:
02098 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
02099 break;
02100
02101 case 0x11: {
02102 uint32 s = buf->ReadDWord();
02103 uint32 t = buf->ReadDWord();
02104 SetNewGRFOverride(s, t);
02105 break;
02106 }
02107
02108 case 0x12: {
02109 if (i == 0) {
02110 if (gvid != 0) {
02111 grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
02112 return CIR_INVALID_ID;
02113 }
02114
02115 free(_cur_grffile->railtype_list);
02116 _cur_grffile->railtype_max = numinfo;
02117 _cur_grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
02118 }
02119
02120 RailTypeLabel rtl = buf->ReadDWord();
02121 _cur_grffile->railtype_list[i] = BSWAP32(rtl);
02122 break;
02123 }
02124
02125 case 0x13:
02126 case 0x14:
02127 while (buf->ReadByte() != 0) {
02128 buf->ReadString();
02129 }
02130 break;
02131
02132 default:
02133 ret = CIR_UNKNOWN;
02134 break;
02135 }
02136 }
02137
02138 return ret;
02139 }
02140
02141
02142 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
02143 {
02144 ChangeInfoResult ret = CIR_SUCCESS;
02145
02146 if (cid + numinfo > NUM_CARGO) {
02147 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
02148 return CIR_INVALID_ID;
02149 }
02150
02151 for (int i = 0; i < numinfo; i++) {
02152 CargoSpec *cs = CargoSpec::Get(cid + i);
02153
02154 switch (prop) {
02155 case 0x08:
02156 cs->bitnum = buf->ReadByte();
02157 if (cs->IsValid()) {
02158 cs->grffile = _cur_grffile;
02159 SetBit(_cargo_mask, cid + i);
02160 } else {
02161 ClrBit(_cargo_mask, cid + i);
02162 }
02163 break;
02164
02165 case 0x09:
02166 cs->name = buf->ReadWord();
02167 _string_to_grf_mapping[&cs->name] = _cur_grffile->grfid;
02168 break;
02169
02170 case 0x0A:
02171 cs->name_single = buf->ReadWord();
02172 _string_to_grf_mapping[&cs->name_single] = _cur_grffile->grfid;
02173 break;
02174
02175 case 0x0B:
02176 case 0x1B:
02177
02178
02179
02180 cs->units_volume = buf->ReadWord();
02181 _string_to_grf_mapping[&cs->units_volume] = _cur_grffile->grfid;
02182 break;
02183
02184 case 0x0C:
02185 case 0x1C:
02186
02187
02188
02189 cs->quantifier = buf->ReadWord();
02190 _string_to_grf_mapping[&cs->quantifier] = _cur_grffile->grfid;
02191 break;
02192
02193 case 0x0D:
02194 cs->abbrev = buf->ReadWord();
02195 _string_to_grf_mapping[&cs->abbrev] = _cur_grffile->grfid;
02196 break;
02197
02198 case 0x0E:
02199 cs->sprite = buf->ReadWord();
02200 break;
02201
02202 case 0x0F:
02203 cs->weight = buf->ReadByte();
02204 break;
02205
02206 case 0x10:
02207 cs->transit_days[0] = buf->ReadByte();
02208 break;
02209
02210 case 0x11:
02211 cs->transit_days[1] = buf->ReadByte();
02212 break;
02213
02214 case 0x12:
02215 cs->initial_payment = buf->ReadDWord();
02216 break;
02217
02218 case 0x13:
02219 cs->rating_colour = MapDOSColour(buf->ReadByte());
02220 break;
02221
02222 case 0x14:
02223 cs->legend_colour = MapDOSColour(buf->ReadByte());
02224 break;
02225
02226 case 0x15:
02227 cs->is_freight = (buf->ReadByte() != 0);
02228 break;
02229
02230 case 0x16:
02231 cs->classes = buf->ReadWord();
02232 break;
02233
02234 case 0x17:
02235 cs->label = buf->ReadDWord();
02236 cs->label = BSWAP32(cs->label);
02237 break;
02238
02239 case 0x18: {
02240 uint8 substitute_type = buf->ReadByte();
02241
02242 switch (substitute_type) {
02243 case 0x00: cs->town_effect = TE_PASSENGERS; break;
02244 case 0x02: cs->town_effect = TE_MAIL; break;
02245 case 0x05: cs->town_effect = TE_GOODS; break;
02246 case 0x09: cs->town_effect = TE_WATER; break;
02247 case 0x0B: cs->town_effect = TE_FOOD; break;
02248 default:
02249 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
02250 case 0xFF: cs->town_effect = TE_NONE; break;
02251 }
02252 break;
02253 }
02254
02255 case 0x19:
02256 cs->multipliertowngrowth = buf->ReadWord();
02257 break;
02258
02259 case 0x1A:
02260 cs->callback_mask = buf->ReadByte();
02261 break;
02262
02263 default:
02264 ret = CIR_UNKNOWN;
02265 break;
02266 }
02267 }
02268
02269 return ret;
02270 }
02271
02272
02273 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
02274 {
02275 ChangeInfoResult ret = CIR_SUCCESS;
02276
02277 if (_cur_grffile->sound_offset == 0) {
02278 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
02279 return CIR_INVALID_ID;
02280 }
02281
02282 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur_grffile->num_sounds) {
02283 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur_grffile->num_sounds);
02284 return CIR_INVALID_ID;
02285 }
02286
02287 for (int i = 0; i < numinfo; i++) {
02288 SoundEntry *sound = GetSound(sid + i + _cur_grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
02289
02290 switch (prop) {
02291 case 0x08:
02292 sound->volume = buf->ReadByte();
02293 break;
02294
02295 case 0x09:
02296 sound->priority = buf->ReadByte();
02297 break;
02298
02299 case 0x0A: {
02300 SoundID orig_sound = buf->ReadByte();
02301
02302 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
02303 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
02304 } else {
02305 SoundEntry *old_sound = GetSound(orig_sound);
02306
02307
02308 *old_sound = *sound;
02309 }
02310 break;
02311 }
02312
02313 default:
02314 ret = CIR_UNKNOWN;
02315 break;
02316 }
02317 }
02318
02319 return ret;
02320 }
02321
02322 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
02323 {
02324 ChangeInfoResult ret = CIR_SUCCESS;
02325
02326 switch (prop) {
02327 case 0x09:
02328 case 0x0D:
02329 case 0x0E:
02330 case 0x10:
02331 case 0x11:
02332 case 0x12:
02333 buf->ReadByte();
02334 break;
02335
02336 case 0x0A:
02337 case 0x0B:
02338 case 0x0C:
02339 case 0x0F:
02340 buf->ReadWord();
02341 break;
02342
02343 default:
02344 ret = CIR_UNKNOWN;
02345 break;
02346 }
02347 return ret;
02348 }
02349
02350 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
02351 {
02352 ChangeInfoResult ret = CIR_SUCCESS;
02353
02354 if (indtid + numinfo > NUM_INDUSTRYTILES) {
02355 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES);
02356 return CIR_INVALID_ID;
02357 }
02358
02359
02360 if (_cur_grffile->indtspec == NULL) {
02361 _cur_grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES);
02362 }
02363
02364 for (int i = 0; i < numinfo; i++) {
02365 IndustryTileSpec *tsp = _cur_grffile->indtspec[indtid + i];
02366
02367 if (prop != 0x08 && tsp == NULL) {
02368 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
02369 if (cir > ret) ret = cir;
02370 continue;
02371 }
02372
02373 switch (prop) {
02374 case 0x08: {
02375 IndustryTileSpec **tilespec = &_cur_grffile->indtspec[indtid + i];
02376 byte subs_id = buf->ReadByte();
02377
02378 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
02379
02380 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
02381 continue;
02382 }
02383
02384
02385 if (*tilespec == NULL) {
02386 *tilespec = CallocT<IndustryTileSpec>(1);
02387 tsp = *tilespec;
02388
02389 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
02390 tsp->enabled = true;
02391
02392
02393
02394
02395 tsp->anim_production = INDUSTRYTILE_NOANIM;
02396 tsp->anim_next = INDUSTRYTILE_NOANIM;
02397
02398 tsp->grf_prop.local_id = indtid + i;
02399 tsp->grf_prop.subst_id = subs_id;
02400 tsp->grf_prop.grffile = _cur_grffile;
02401 _industile_mngr.AddEntityID(indtid + i, _cur_grffile->grfid, subs_id);
02402 }
02403 break;
02404 }
02405
02406 case 0x09: {
02407 byte ovrid = buf->ReadByte();
02408
02409
02410 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
02411 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
02412 continue;
02413 }
02414
02415 _industile_mngr.Add(indtid + i, _cur_grffile->grfid, ovrid);
02416 break;
02417 }
02418
02419 case 0x0A:
02420 case 0x0B:
02421 case 0x0C: {
02422 uint16 acctp = buf->ReadWord();
02423 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
02424 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
02425 break;
02426 }
02427
02428 case 0x0D:
02429 tsp->slopes_refused = (Slope)buf->ReadByte();
02430 break;
02431
02432 case 0x0E:
02433 tsp->callback_mask = buf->ReadByte();
02434 break;
02435
02436 case 0x0F:
02437 tsp->animation.frames = buf->ReadByte();
02438 tsp->animation.status = buf->ReadByte();
02439 break;
02440
02441 case 0x10:
02442 tsp->animation.speed = buf->ReadByte();
02443 break;
02444
02445 case 0x11:
02446 tsp->animation.triggers = buf->ReadByte();
02447 break;
02448
02449 case 0x12:
02450 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
02451 break;
02452
02453 default:
02454 ret = CIR_UNKNOWN;
02455 break;
02456 }
02457 }
02458
02459 return ret;
02460 }
02461
02462 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
02463 {
02464 ChangeInfoResult ret = CIR_SUCCESS;
02465
02466 switch (prop) {
02467 case 0x09:
02468 case 0x0B:
02469 case 0x0F:
02470 case 0x12:
02471 case 0x13:
02472 case 0x14:
02473 case 0x17:
02474 case 0x18:
02475 case 0x19:
02476 case 0x21:
02477 case 0x22:
02478 buf->ReadByte();
02479 break;
02480
02481 case 0x0C:
02482 case 0x0D:
02483 case 0x0E:
02484 case 0x10:
02485 case 0x1B:
02486 case 0x1F:
02487 case 0x24:
02488 buf->ReadWord();
02489 break;
02490
02491 case 0x11:
02492 case 0x1A:
02493 case 0x1C:
02494 case 0x1D:
02495 case 0x1E:
02496 case 0x20:
02497 case 0x23:
02498 buf->ReadDWord();
02499 break;
02500
02501 case 0x0A: {
02502 byte num_table = buf->ReadByte();
02503 for (byte j = 0; j < num_table; j++) {
02504 for (uint k = 0;; k++) {
02505 byte x = buf->ReadByte();
02506 if (x == 0xFE && k == 0) {
02507 buf->ReadByte();
02508 buf->ReadByte();
02509 break;
02510 }
02511
02512 byte y = buf->ReadByte();
02513 if (x == 0 && y == 0x80) break;
02514
02515 byte gfx = buf->ReadByte();
02516 if (gfx == 0xFE) buf->ReadWord();
02517 }
02518 }
02519 break;
02520 }
02521
02522 case 0x16:
02523 for (byte j = 0; j < 3; j++) buf->ReadByte();
02524 break;
02525
02526 case 0x15: {
02527 byte number_of_sounds = buf->ReadByte();
02528 for (uint8 j = 0; j < number_of_sounds; j++) {
02529 buf->ReadByte();
02530 }
02531 break;
02532 }
02533
02534 default:
02535 ret = CIR_UNKNOWN;
02536 break;
02537 }
02538 return ret;
02539 }
02540
02547 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
02548 {
02549 for (int i = 0; i < size - 1; i++) {
02550 for (int j = i + 1; j < size; j++) {
02551 if (layout[i].ti.x == layout[j].ti.x &&
02552 layout[i].ti.y == layout[j].ti.y) {
02553 return false;
02554 }
02555 }
02556 }
02557 return true;
02558 }
02559
02561 static void CleanIndustryTileTable(IndustrySpec *ind)
02562 {
02563 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
02564 for (int j = 0; j < ind->num_table; j++) {
02565
02566 free((void*)ind->table[j]);
02567 }
02568
02569 free((void*)ind->table);
02570 ind->table = NULL;
02571 }
02572 }
02573
02574 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
02575 {
02576 ChangeInfoResult ret = CIR_SUCCESS;
02577
02578 if (indid + numinfo > NUM_INDUSTRYTYPES) {
02579 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
02580 return CIR_INVALID_ID;
02581 }
02582
02583 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
02584
02585
02586 if (_cur_grffile->industryspec == NULL) {
02587 _cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
02588 }
02589
02590 for (int i = 0; i < numinfo; i++) {
02591 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
02592
02593 if (prop != 0x08 && indsp == NULL) {
02594 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
02595 if (cir > ret) ret = cir;
02596 continue;
02597 }
02598
02599 switch (prop) {
02600 case 0x08: {
02601 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
02602 byte subs_id = buf->ReadByte();
02603
02604 if (subs_id == 0xFF) {
02605
02606
02607 _industry_specs[indid + i].enabled = false;
02608 continue;
02609 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
02610
02611 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
02612 continue;
02613 }
02614
02615
02616
02617
02618 if (*indspec == NULL) {
02619 *indspec = CallocT<IndustrySpec>(1);
02620 indsp = *indspec;
02621
02622 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
02623 indsp->enabled = true;
02624 indsp->grf_prop.local_id = indid + i;
02625 indsp->grf_prop.subst_id = subs_id;
02626 indsp->grf_prop.grffile = _cur_grffile;
02627
02628
02629 indsp->check_proc = CHECK_NOTHING;
02630 }
02631 break;
02632 }
02633
02634 case 0x09: {
02635 byte ovrid = buf->ReadByte();
02636
02637
02638 if (ovrid >= NEW_INDUSTRYOFFSET) {
02639 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
02640 continue;
02641 }
02642 indsp->grf_prop.override = ovrid;
02643 _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
02644 break;
02645 }
02646
02647 case 0x0A: {
02648 byte new_num_layouts = buf->ReadByte();
02649
02650
02651
02652
02653
02654 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
02655 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts);
02656 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles);
02657 uint size;
02658 const IndustryTileTable *copy_from;
02659
02660 try {
02661 for (byte j = 0; j < new_num_layouts; j++) {
02662 for (uint k = 0;; k++) {
02663 if (k >= def_num_tiles) {
02664 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
02665
02666 def_num_tiles *= 2;
02667 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
02668 }
02669
02670 itt[k].ti.x = buf->ReadByte();
02671
02672 if (itt[k].ti.x == 0xFE && k == 0) {
02673
02674 IndustryType type = buf->ReadByte();
02675 byte laynbr = buf->ReadByte();
02676
02677 copy_from = _origin_industry_specs[type].table[laynbr];
02678 for (size = 1;; size++) {
02679 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
02680 }
02681 break;
02682 }
02683
02684 itt[k].ti.y = buf->ReadByte();
02685
02686 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
02687
02688
02689 itt[k].ti.x = -0x80;
02690 itt[k].ti.y = 0;
02691 itt[k].gfx = 0;
02692
02693 size = k + 1;
02694 copy_from = itt;
02695 break;
02696 }
02697
02698 itt[k].gfx = buf->ReadByte();
02699
02700 if (itt[k].gfx == 0xFE) {
02701
02702 int local_tile_id = buf->ReadWord();
02703
02704
02705 int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
02706
02707 if (tempid == INVALID_INDUSTRYTILE) {
02708 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
02709 } else {
02710
02711 itt[k].gfx = tempid;
02712 size = k + 1;
02713 copy_from = itt;
02714 }
02715 } else if (itt[k].gfx == 0xFF) {
02716 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
02717 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
02718 }
02719 }
02720
02721 if (!ValidateIndustryLayout(copy_from, size)) {
02722
02723 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
02724 new_num_layouts--;
02725 j--;
02726 } else {
02727 tile_table[j] = CallocT<IndustryTileTable>(size);
02728 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
02729 }
02730 }
02731 } catch (...) {
02732 for (int i = 0; i < new_num_layouts; i++) {
02733 free(tile_table[i]);
02734 }
02735 free(tile_table);
02736 free(itt);
02737 throw;
02738 }
02739
02740
02741 CleanIndustryTileTable(indsp);
02742
02743 indsp->num_table = new_num_layouts;
02744 indsp->table = tile_table;
02745 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
02746 free(itt);
02747 break;
02748 }
02749
02750 case 0x0B:
02751 indsp->life_type = (IndustryLifeType)buf->ReadByte();
02752 break;
02753
02754 case 0x0C:
02755 indsp->closure_text = buf->ReadWord();
02756 _string_to_grf_mapping[&indsp->closure_text] = _cur_grffile->grfid;
02757 break;
02758
02759 case 0x0D:
02760 indsp->production_up_text = buf->ReadWord();
02761 _string_to_grf_mapping[&indsp->production_up_text] = _cur_grffile->grfid;
02762 break;
02763
02764 case 0x0E:
02765 indsp->production_down_text = buf->ReadWord();
02766 _string_to_grf_mapping[&indsp->production_down_text] = _cur_grffile->grfid;
02767 break;
02768
02769 case 0x0F:
02770 indsp->cost_multiplier = buf->ReadByte();
02771 break;
02772
02773 case 0x10:
02774 for (byte j = 0; j < 2; j++) {
02775 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02776 }
02777 break;
02778
02779 case 0x11:
02780 for (byte j = 0; j < 3; j++) {
02781 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur_grffile);
02782 }
02783 buf->ReadByte();
02784 break;
02785
02786 case 0x12:
02787 case 0x13:
02788 indsp->production_rate[prop - 0x12] = buf->ReadByte();
02789 break;
02790
02791 case 0x14:
02792 indsp->minimal_cargo = buf->ReadByte();
02793 break;
02794
02795 case 0x15: {
02796 indsp->number_of_sounds = buf->ReadByte();
02797 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
02798
02799 try {
02800 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
02801 sounds[j] = buf->ReadByte();
02802 }
02803 } catch (...) {
02804 free(sounds);
02805 throw;
02806 }
02807
02808 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
02809 free((void*)indsp->random_sounds);
02810 }
02811 indsp->random_sounds = sounds;
02812 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
02813 break;
02814 }
02815
02816 case 0x16:
02817 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
02818 break;
02819
02820 case 0x17:
02821 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
02822 break;
02823
02824 case 0x18:
02825 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
02826 break;
02827
02828 case 0x19:
02829 indsp->map_colour = MapDOSColour(buf->ReadByte());
02830 break;
02831
02832 case 0x1A:
02833 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
02834 break;
02835
02836 case 0x1B:
02837 indsp->new_industry_text = buf->ReadWord();
02838 _string_to_grf_mapping[&indsp->new_industry_text] = _cur_grffile->grfid;
02839 break;
02840
02841 case 0x1C:
02842 case 0x1D:
02843 case 0x1E: {
02844 uint32 multiples = buf->ReadDWord();
02845 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
02846 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
02847 break;
02848 }
02849
02850 case 0x1F:
02851 indsp->name = buf->ReadWord();
02852 _string_to_grf_mapping[&indsp->name] = _cur_grffile->grfid;
02853 break;
02854
02855 case 0x20:
02856 indsp->prospecting_chance = buf->ReadDWord();
02857 break;
02858
02859 case 0x21:
02860 case 0x22: {
02861 byte aflag = buf->ReadByte();
02862 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
02863 break;
02864 }
02865
02866 case 0x23:
02867 indsp->removal_cost_multiplier = buf->ReadDWord();
02868 break;
02869
02870 case 0x24:
02871 indsp->station_name = buf->ReadWord();
02872 if (indsp->station_name != STR_NULL) _string_to_grf_mapping[&indsp->station_name] = _cur_grffile->grfid;
02873 break;
02874
02875 default:
02876 ret = CIR_UNKNOWN;
02877 break;
02878 }
02879 }
02880
02881 return ret;
02882 }
02883
02889 static void DuplicateTileTable(AirportSpec *as)
02890 {
02891 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
02892 for (int i = 0; i < as->num_table; i++) {
02893 uint num_tiles = 1;
02894 const AirportTileTable *it = as->table[0];
02895 do {
02896 num_tiles++;
02897 } while ((++it)->ti.x != -0x80);
02898 table_list[i] = MallocT<AirportTileTable>(num_tiles);
02899 MemCpyT(table_list[i], as->table[i], num_tiles);
02900 }
02901 as->table = table_list;
02902 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
02903 MemCpyT(depot_table, as->depot_table, as->nof_depots);
02904 as->depot_table = depot_table;
02905 }
02906
02907 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
02908 {
02909 ChangeInfoResult ret = CIR_SUCCESS;
02910
02911 if (airport + numinfo > NUM_AIRPORTS) {
02912 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS);
02913 return CIR_INVALID_ID;
02914 }
02915
02916 grfmsg(1, "AirportChangeInfo: newid %u", airport);
02917
02918
02919 if (_cur_grffile->airportspec == NULL) {
02920 _cur_grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS);
02921 }
02922
02923 for (int i = 0; i < numinfo; i++) {
02924 AirportSpec *as = _cur_grffile->airportspec[airport + i];
02925
02926 if (as == NULL && prop != 0x08 && prop != 0x09) {
02927 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
02928 return CIR_INVALID_ID;
02929 }
02930
02931 switch (prop) {
02932 case 0x08: {
02933 byte subs_id = buf->ReadByte();
02934
02935 if (subs_id == 0xFF) {
02936
02937
02938 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
02939 continue;
02940 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
02941
02942 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
02943 continue;
02944 }
02945
02946 AirportSpec **spec = &_cur_grffile->airportspec[airport + i];
02947
02948
02949
02950 if (*spec == NULL) {
02951 *spec = MallocT<AirportSpec>(1);
02952 as = *spec;
02953
02954 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
02955 as->enabled = true;
02956 as->grf_prop.local_id = airport + i;
02957 as->grf_prop.subst_id = subs_id;
02958 as->grf_prop.grffile = _cur_grffile;
02959
02960 _airport_mngr.Add(airport + i, _cur_grffile->grfid, subs_id);
02961
02962 DuplicateTileTable(as);
02963 }
02964 break;
02965 }
02966
02967 case 0x0A: {
02968 as->num_table = buf->ReadByte();
02969 as->rotation = MallocT<Direction>(as->num_table);
02970 uint32 defsize = buf->ReadDWord();
02971 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table);
02972 AirportTileTable *att = CallocT<AirportTileTable>(defsize);
02973 int size;
02974 const AirportTileTable *copy_from;
02975 try {
02976 for (byte j = 0; j < as->num_table; j++) {
02977 as->rotation[j] = (Direction)buf->ReadByte();
02978 for (int k = 0;; k++) {
02979 att[k].ti.x = buf->ReadByte();
02980 att[k].ti.y = buf->ReadByte();
02981
02982 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
02983
02984
02985 att[k].ti.x = -0x80;
02986 att[k].ti.y = 0;
02987 att[k].gfx = 0;
02988
02989 size = k + 1;
02990 copy_from = att;
02991 break;
02992 }
02993
02994 att[k].gfx = buf->ReadByte();
02995
02996 if (att[k].gfx == 0xFE) {
02997
02998 int local_tile_id = buf->ReadWord();
02999
03000
03001 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
03002
03003 if (tempid == INVALID_AIRPORTTILE) {
03004 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
03005 } else {
03006
03007 att[k].gfx = tempid;
03008 size = k + 1;
03009 copy_from = att;
03010 }
03011 } else if (att[k].gfx == 0xFF) {
03012 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
03013 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
03014 }
03015
03016 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
03017 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
03018 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
03019 } else {
03020 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
03021 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
03022 }
03023 }
03024 tile_table[j] = CallocT<AirportTileTable>(size);
03025 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
03026 }
03027
03028 as->table = tile_table;
03029 free(att);
03030 } catch (...) {
03031 for (int i = 0; i < as->num_table; i++) {
03032 free(tile_table[i]);
03033 }
03034 free(tile_table);
03035 free(att);
03036 throw;
03037 }
03038 break;
03039 }
03040
03041 case 0x0C:
03042 as->min_year = buf->ReadWord();
03043 as->max_year = buf->ReadWord();
03044 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
03045 break;
03046
03047 case 0x0D:
03048 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
03049 break;
03050
03051 case 0x0E:
03052 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
03053 break;
03054
03055 case 0x0F:
03056 as->noise_level = buf->ReadByte();
03057 break;
03058
03059 case 0x10:
03060 as->name = buf->ReadWord();
03061 _string_to_grf_mapping[&as->name] = _cur_grffile->grfid;
03062 break;
03063
03064 default:
03065 ret = CIR_UNKNOWN;
03066 break;
03067 }
03068 }
03069
03070 return ret;
03071 }
03072
03073 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
03074 {
03075 ChangeInfoResult ret = CIR_SUCCESS;
03076
03077 switch (prop) {
03078 case 0x0B:
03079 case 0x0C:
03080 case 0x0D:
03081 case 0x12:
03082 case 0x14:
03083 case 0x16:
03084 case 0x17:
03085 buf->ReadByte();
03086
03087 case 0x09:
03088 case 0x0A:
03089 case 0x10:
03090 case 0x11:
03091 case 0x13:
03092 case 0x15:
03093 buf->ReadWord();
03094 break;
03095
03096 case 0x08:
03097 case 0x0E:
03098 case 0x0F:
03099 buf->ReadDWord();
03100 break;
03101
03102 default:
03103 ret = CIR_UNKNOWN;
03104 break;
03105 }
03106
03107 return ret;
03108 }
03109
03110 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03111 {
03112 ChangeInfoResult ret = CIR_SUCCESS;
03113
03114 if (id + numinfo > NUM_OBJECTS) {
03115 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS);
03116 return CIR_INVALID_ID;
03117 }
03118
03119
03120 if (_cur_grffile->objectspec == NULL) {
03121 _cur_grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS);
03122 }
03123
03124 for (int i = 0; i < numinfo; i++) {
03125 ObjectSpec *spec = _cur_grffile->objectspec[id + i];
03126
03127 if (prop != 0x08 && spec == NULL) {
03128
03129 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
03130 if (cir > ret) ret = cir;
03131 continue;
03132 }
03133
03134 switch (prop) {
03135 case 0x08: {
03136 ObjectSpec **ospec = &_cur_grffile->objectspec[id + i];
03137
03138
03139 if (*ospec == NULL) {
03140 *ospec = CallocT<ObjectSpec>(1);
03141 (*ospec)->views = 1;
03142 }
03143
03144
03145 uint32 classid = buf->ReadDWord();
03146 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
03147 (*ospec)->enabled = true;
03148 break;
03149 }
03150
03151 case 0x09: {
03152 StringID class_name = buf->ReadWord();
03153 ObjectClass::SetName(spec->cls_id, class_name);
03154 _string_to_grf_mapping[&ObjectClass::classes[spec->cls_id].name] = _cur_grffile->grfid;
03155 break;
03156 }
03157
03158 case 0x0A:
03159 spec->name = buf->ReadWord();
03160 _string_to_grf_mapping[&spec->name] = _cur_grffile->grfid;
03161 break;
03162
03163 case 0x0B:
03164 spec->climate = buf->ReadByte();
03165 break;
03166
03167 case 0x0C:
03168 spec->size = buf->ReadByte();
03169 break;
03170
03171 case 0x0D:
03172 spec->build_cost_multiplier = buf->ReadByte();
03173 spec->clear_cost_multiplier = spec->build_cost_multiplier;
03174 break;
03175
03176 case 0x0E:
03177 spec->introduction_date = buf->ReadDWord();
03178 break;
03179
03180 case 0x0F:
03181 spec->end_of_life_date = buf->ReadDWord();
03182 break;
03183
03184 case 0x10:
03185 spec->flags = (ObjectFlags)buf->ReadWord();
03186 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
03187 break;
03188
03189 case 0x11:
03190 spec->animation.frames = buf->ReadByte();
03191 spec->animation.status = buf->ReadByte();
03192 break;
03193
03194 case 0x12:
03195 spec->animation.speed = buf->ReadByte();
03196 break;
03197
03198 case 0x13:
03199 spec->animation.triggers = buf->ReadWord();
03200 break;
03201
03202 case 0x14:
03203 spec->clear_cost_multiplier = buf->ReadByte();
03204 break;
03205
03206 case 0x15:
03207 spec->callback_mask = buf->ReadWord();
03208 break;
03209
03210 case 0x16:
03211 spec->height = buf->ReadByte();
03212 break;
03213
03214 case 0x17:
03215 spec->views = buf->ReadByte();
03216 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
03217 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
03218 spec->views = 1;
03219 }
03220 break;
03221
03222 default:
03223 ret = CIR_UNKNOWN;
03224 break;
03225 }
03226 }
03227
03228 return ret;
03229 }
03230
03231 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
03232 {
03233 ChangeInfoResult ret = CIR_SUCCESS;
03234
03235 extern RailtypeInfo _railtypes[RAILTYPE_END];
03236
03237 if (id + numinfo > RAILTYPE_END) {
03238 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03239 return CIR_INVALID_ID;
03240 }
03241
03242 for (int i = 0; i < numinfo; i++) {
03243 RailType rt = _cur_grffile->railtype_map[id + i];
03244 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
03245
03246 RailtypeInfo *rti = &_railtypes[rt];
03247
03248 switch (prop) {
03249 case 0x08:
03250
03251 buf->ReadDWord();
03252 break;
03253
03254 case 0x09:
03255 rti->strings.toolbar_caption = buf->ReadWord();
03256 _string_to_grf_mapping[&rti->strings.toolbar_caption] = _cur_grffile->grfid;
03257 break;
03258
03259 case 0x0A:
03260 rti->strings.menu_text = buf->ReadWord();
03261 _string_to_grf_mapping[&rti->strings.menu_text] = _cur_grffile->grfid;
03262 break;
03263
03264 case 0x0B:
03265 rti->strings.build_caption = buf->ReadWord();
03266 _string_to_grf_mapping[&rti->strings.build_caption] = _cur_grffile->grfid;
03267 break;
03268
03269 case 0x0C:
03270 rti->strings.replace_text = buf->ReadWord();
03271 _string_to_grf_mapping[&rti->strings.replace_text] = _cur_grffile->grfid;
03272 break;
03273
03274 case 0x0D:
03275 rti->strings.new_loco = buf->ReadWord();
03276 _string_to_grf_mapping[&rti->strings.new_loco] = _cur_grffile->grfid;
03277 break;
03278
03279 case 0x0E:
03280 case 0x0F:
03281 case 0x18:
03282 case 0x19:
03283 {
03284
03285
03286
03287 int n = buf->ReadByte();
03288 for (int j = 0; j != n; j++) {
03289 RailTypeLabel label = buf->ReadDWord();
03290 RailType rt = GetRailTypeByLabel(BSWAP32(label));
03291 if (rt != INVALID_RAILTYPE) {
03292 switch (prop) {
03293 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
03294 case 0x0F: SetBit(rti->powered_railtypes, rt); break;
03295 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
03296 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
03297 }
03298 }
03299 }
03300 break;
03301 }
03302
03303 case 0x10:
03304 rti->flags = (RailTypeFlags)buf->ReadByte();
03305 break;
03306
03307 case 0x11:
03308 rti->curve_speed = buf->ReadByte();
03309 break;
03310
03311 case 0x12:
03312 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
03313 break;
03314
03315 case 0x13:
03316 rti->cost_multiplier = buf->ReadWord();
03317 break;
03318
03319 case 0x14:
03320 rti->max_speed = buf->ReadWord();
03321 break;
03322
03323 case 0x15:
03324 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
03325 break;
03326
03327 case 0x16:
03328 rti->map_colour = MapDOSColour(buf->ReadByte());
03329 break;
03330
03331 case 0x17:
03332 rti->introduction_date = buf->ReadDWord();
03333 break;
03334
03335 case 0x1A:
03336 rti->sorting_order = buf->ReadByte();
03337 break;
03338
03339 default:
03340 ret = CIR_UNKNOWN;
03341 break;
03342 }
03343 }
03344
03345 return ret;
03346 }
03347
03348 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
03349 {
03350 ChangeInfoResult ret = CIR_SUCCESS;
03351
03352 if (id + numinfo > RAILTYPE_END) {
03353 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
03354 return CIR_INVALID_ID;
03355 }
03356
03357 for (int i = 0; i < numinfo; i++) {
03358 switch (prop) {
03359 case 0x08:
03360 {
03361 RailTypeLabel rtl = buf->ReadDWord();
03362 rtl = BSWAP32(rtl);
03363
03364 RailType rt = GetRailTypeByLabel(rtl);
03365 if (rt == INVALID_RAILTYPE) {
03366
03367 rt = AllocateRailType(rtl);
03368 }
03369
03370 _cur_grffile->railtype_map[id + i] = rt;
03371 break;
03372 }
03373
03374 case 0x09:
03375 case 0x0A:
03376 case 0x0B:
03377 case 0x0C:
03378 case 0x0D:
03379 case 0x13:
03380 case 0x14:
03381 buf->ReadWord();
03382 break;
03383
03384 case 0x0E:
03385 case 0x0F:
03386 case 0x18:
03387 case 0x19:
03388 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
03389 break;
03390
03391 case 0x10:
03392 case 0x11:
03393 case 0x12:
03394 case 0x15:
03395 case 0x16:
03396 case 0x1A:
03397 buf->ReadByte();
03398 break;
03399
03400 case 0x17:
03401 buf->ReadDWord();
03402 break;
03403
03404 default:
03405 ret = CIR_UNKNOWN;
03406 break;
03407 }
03408 }
03409
03410 return ret;
03411 }
03412
03413 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
03414 {
03415 ChangeInfoResult ret = CIR_SUCCESS;
03416
03417 if (airtid + numinfo > NUM_AIRPORTTILES) {
03418 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES);
03419 return CIR_INVALID_ID;
03420 }
03421
03422
03423 if (_cur_grffile->airtspec == NULL) {
03424 _cur_grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES);
03425 }
03426
03427 for (int i = 0; i < numinfo; i++) {
03428 AirportTileSpec *tsp = _cur_grffile->airtspec[airtid + i];
03429
03430 if (prop != 0x08 && tsp == NULL) {
03431 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
03432 return CIR_INVALID_ID;
03433 }
03434
03435 switch (prop) {
03436 case 0x08: {
03437 AirportTileSpec **tilespec = &_cur_grffile->airtspec[airtid + i];
03438 byte subs_id = buf->ReadByte();
03439
03440 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
03441
03442 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
03443 continue;
03444 }
03445
03446
03447 if (*tilespec == NULL) {
03448 *tilespec = CallocT<AirportTileSpec>(1);
03449 tsp = *tilespec;
03450
03451 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
03452 tsp->enabled = true;
03453
03454 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
03455
03456 tsp->grf_prop.local_id = airtid + i;
03457 tsp->grf_prop.subst_id = subs_id;
03458 tsp->grf_prop.grffile = _cur_grffile;
03459 _airporttile_mngr.AddEntityID(airtid + i, _cur_grffile->grfid, subs_id);
03460 }
03461 break;
03462 }
03463
03464 case 0x09: {
03465 byte override = buf->ReadByte();
03466
03467
03468 if (override >= NEW_AIRPORTTILE_OFFSET) {
03469 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
03470 continue;
03471 }
03472
03473 _airporttile_mngr.Add(airtid + i, _cur_grffile->grfid, override);
03474 break;
03475 }
03476
03477 case 0x0E:
03478 tsp->callback_mask = buf->ReadByte();
03479 break;
03480
03481 case 0x0F:
03482 tsp->animation.frames = buf->ReadByte();
03483 tsp->animation.status = buf->ReadByte();
03484 break;
03485
03486 case 0x10:
03487 tsp->animation.speed = buf->ReadByte();
03488 break;
03489
03490 case 0x11:
03491 tsp->animation.triggers = buf->ReadByte();
03492 break;
03493
03494 default:
03495 ret = CIR_UNKNOWN;
03496 break;
03497 }
03498 }
03499
03500 return ret;
03501 }
03502
03503 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
03504 {
03505 switch (cir) {
03506 default: NOT_REACHED();
03507
03508 case CIR_SUCCESS:
03509 return false;
03510
03511 case CIR_UNHANDLED:
03512 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
03513 return false;
03514
03515 case CIR_UNKNOWN:
03516 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
03517
03518
03519 case CIR_INVALID_ID:
03520
03521 DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
03522 return true;
03523 }
03524 }
03525
03526
03527 static void FeatureChangeInfo(ByteReader *buf)
03528 {
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540 static const VCI_Handler handler[] = {
03541 RailVehicleChangeInfo,
03542 RoadVehicleChangeInfo,
03543 ShipVehicleChangeInfo,
03544 AircraftVehicleChangeInfo,
03545 StationChangeInfo,
03546 CanalChangeInfo,
03547 BridgeChangeInfo,
03548 TownHouseChangeInfo,
03549 GlobalVarChangeInfo,
03550 IndustrytilesChangeInfo,
03551 IndustriesChangeInfo,
03552 NULL,
03553 SoundEffectChangeInfo,
03554 AirportChangeInfo,
03555 NULL,
03556 ObjectChangeInfo,
03557 RailTypeChangeInfo,
03558 AirportTilesChangeInfo,
03559 };
03560
03561 uint8 feature = buf->ReadByte();
03562 uint8 numprops = buf->ReadByte();
03563 uint numinfo = buf->ReadByte();
03564 uint engine = buf->ReadExtendedByte();
03565
03566 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
03567 feature, numprops, engine, numinfo);
03568
03569 if (feature >= lengthof(handler) || handler[feature] == NULL) {
03570 if (feature != GSF_CARGOS) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
03571 return;
03572 }
03573
03574
03575 SetBit(_cur_grffile->grf_features, feature);
03576
03577 while (numprops-- && buf->HasData()) {
03578 uint8 prop = buf->ReadByte();
03579
03580 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
03581 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
03582 }
03583 }
03584
03585
03586 static void SafeChangeInfo(ByteReader *buf)
03587 {
03588 uint8 feature = buf->ReadByte();
03589 uint8 numprops = buf->ReadByte();
03590 uint numinfo = buf->ReadByte();
03591 buf->ReadExtendedByte();
03592
03593 if (feature == GSF_BRIDGES && numprops == 1) {
03594 uint8 prop = buf->ReadByte();
03595
03596
03597 if (prop == 0x0D) return;
03598 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
03599 uint8 prop = buf->ReadByte();
03600
03601 if (prop == 0x11) {
03602 bool is_safe = true;
03603 for (uint i = 0; i < numinfo; i++) {
03604 uint32 s = buf->ReadDWord();
03605 buf->ReadDWord();
03606 const GRFConfig *grfconfig = GetGRFConfig(s);
03607 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
03608 is_safe = false;
03609 break;
03610 }
03611 }
03612 if (is_safe) return;
03613 }
03614 }
03615
03616 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
03617
03618
03619 _skip_sprites = -1;
03620 }
03621
03622
03623 static void ReserveChangeInfo(ByteReader *buf)
03624 {
03625 uint8 feature = buf->ReadByte();
03626
03627 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
03628
03629 uint8 numprops = buf->ReadByte();
03630 uint8 numinfo = buf->ReadByte();
03631 uint8 index = buf->ReadExtendedByte();
03632
03633 while (numprops-- && buf->HasData()) {
03634 uint8 prop = buf->ReadByte();
03635 ChangeInfoResult cir = CIR_SUCCESS;
03636
03637 switch (feature) {
03638 default: NOT_REACHED();
03639 case GSF_CARGOS:
03640 cir = CargoChangeInfo(index, numinfo, prop, buf);
03641 break;
03642
03643 case GSF_GLOBALVAR:
03644 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
03645 break;
03646
03647 case GSF_RAILTYPES:
03648 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
03649 break;
03650 }
03651
03652 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
03653 }
03654 }
03655
03656
03657 static void NewSpriteSet(ByteReader *buf)
03658 {
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671 uint8 feature = buf->ReadByte();
03672 uint8 num_sets = buf->ReadByte();
03673 uint16 num_ents = buf->ReadExtendedByte();
03674
03675 _cur_grffile->spriteset_start = _cur_spriteid;
03676 _cur_grffile->spriteset_feature = feature;
03677 _cur_grffile->spriteset_numsets = num_sets;
03678 _cur_grffile->spriteset_numents = num_ents;
03679
03680 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
03681 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
03682 );
03683
03684 for (int i = 0; i < num_sets * num_ents; i++) {
03685 _nfo_line++;
03686 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
03687 }
03688 }
03689
03690
03691 static void SkipAct1(ByteReader *buf)
03692 {
03693 buf->ReadByte();
03694 uint8 num_sets = buf->ReadByte();
03695 uint16 num_ents = buf->ReadExtendedByte();
03696
03697 _skip_sprites = num_sets * num_ents;
03698
03699 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
03700 }
03701
03702
03703
03704 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
03705 {
03706 if (HasBit(groupid, 15)) {
03707 assert(CallbackResultSpriteGroup::CanAllocateItem());
03708 return new CallbackResultSpriteGroup(groupid);
03709 }
03710
03711 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03712 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
03713 return NULL;
03714 }
03715
03716 return _cur_grffile->spritegroups[groupid];
03717 }
03718
03719
03720 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
03721 {
03722 if (HasBit(spriteid, 15)) {
03723 assert(CallbackResultSpriteGroup::CanAllocateItem());
03724 return new CallbackResultSpriteGroup(spriteid);
03725 }
03726
03727 if (spriteid >= _cur_grffile->spriteset_numsets) {
03728 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
03729 return NULL;
03730 }
03731
03732
03733
03734
03735 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
03736 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
03737 setid, type,
03738 _cur_grffile->spriteset_start + spriteid * num_sprites,
03739 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
03740 return NULL;
03741 }
03742
03743 if (feature != _cur_grffile->spriteset_feature) {
03744 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
03745 setid, type,
03746 _cur_grffile->spriteset_feature, feature);
03747 return NULL;
03748 }
03749
03750 assert(ResultSpriteGroup::CanAllocateItem());
03751 return new ResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
03752 }
03753
03754
03755 static void NewSpriteGroup(ByteReader *buf)
03756 {
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767 SpriteGroup *act_group = NULL;
03768
03769 uint8 feature = buf->ReadByte();
03770 uint8 setid = buf->ReadByte();
03771 uint8 type = buf->ReadByte();
03772
03773 if (setid >= _cur_grffile->spritegroups_count) {
03774
03775 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
03776
03777 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++) {
03778 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
03779 }
03780 }
03781
03782
03783
03784
03785
03786 switch (type) {
03787
03788 case 0x81:
03789 case 0x82:
03790 case 0x85:
03791 case 0x86:
03792 case 0x89:
03793 case 0x8A:
03794 {
03795 byte varadjust;
03796 byte varsize;
03797
03798 assert(DeterministicSpriteGroup::CanAllocateItem());
03799 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
03800 act_group = group;
03801 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03802
03803 switch (GB(type, 2, 2)) {
03804 default: NOT_REACHED();
03805 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
03806 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
03807 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
03808 }
03809
03810
03811
03812 do {
03813 DeterministicSpriteGroupAdjust *adjust;
03814
03815 group->num_adjusts++;
03816 group->adjusts = ReallocT(group->adjusts, group->num_adjusts);
03817
03818 adjust = &group->adjusts[group->num_adjusts - 1];
03819
03820
03821 adjust->operation = group->num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
03822 adjust->variable = buf->ReadByte();
03823 if (adjust->variable == 0x7E) {
03824
03825 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
03826 } else {
03827 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
03828 }
03829
03830 varadjust = buf->ReadByte();
03831 adjust->shift_num = GB(varadjust, 0, 5);
03832 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
03833 adjust->and_mask = buf->ReadVarSize(varsize);
03834
03835 if (adjust->type != DSGA_TYPE_NONE) {
03836 adjust->add_val = buf->ReadVarSize(varsize);
03837 adjust->divmod_val = buf->ReadVarSize(varsize);
03838 } else {
03839 adjust->add_val = 0;
03840 adjust->divmod_val = 0;
03841 }
03842
03843
03844 } while (HasBit(varadjust, 5));
03845
03846 group->num_ranges = buf->ReadByte();
03847 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
03848
03849 for (uint i = 0; i < group->num_ranges; i++) {
03850 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
03851 group->ranges[i].low = buf->ReadVarSize(varsize);
03852 group->ranges[i].high = buf->ReadVarSize(varsize);
03853 }
03854
03855 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
03856 break;
03857 }
03858
03859
03860 case 0x80:
03861 case 0x83:
03862 case 0x84:
03863 {
03864 assert(RandomizedSpriteGroup::CanAllocateItem());
03865 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
03866 act_group = group;
03867 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
03868
03869 if (HasBit(type, 2)) {
03870 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
03871 group->count = buf->ReadByte();
03872 }
03873
03874 uint8 triggers = buf->ReadByte();
03875 group->triggers = GB(triggers, 0, 7);
03876 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
03877 group->lowest_randbit = buf->ReadByte();
03878 group->num_groups = buf->ReadByte();
03879 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
03880
03881 for (uint i = 0; i < group->num_groups; i++) {
03882 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
03883 }
03884
03885 break;
03886 }
03887
03888
03889 default:
03890 {
03891 switch (feature) {
03892 case GSF_TRAINS:
03893 case GSF_ROADVEHICLES:
03894 case GSF_SHIPS:
03895 case GSF_AIRCRAFT:
03896 case GSF_STATIONS:
03897 case GSF_CANALS:
03898 case GSF_CARGOS:
03899 case GSF_AIRPORTS:
03900 case GSF_RAILTYPES:
03901 {
03902 byte sprites = _cur_grffile->spriteset_numents;
03903 byte num_loaded = type;
03904 byte num_loading = buf->ReadByte();
03905
03906 if (_cur_grffile->spriteset_start == 0) {
03907 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
03908 return;
03909 }
03910
03911 assert(RealSpriteGroup::CanAllocateItem());
03912 RealSpriteGroup *group = new RealSpriteGroup();
03913 act_group = group;
03914
03915 group->num_loaded = num_loaded;
03916 group->num_loading = num_loading;
03917 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
03918 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
03919
03920 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
03921 setid, sprites, num_loaded, num_loading);
03922
03923 for (uint i = 0; i < num_loaded; i++) {
03924 uint16 spriteid = buf->ReadWord();
03925 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03926 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
03927 }
03928
03929 for (uint i = 0; i < num_loading; i++) {
03930 uint16 spriteid = buf->ReadWord();
03931 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
03932 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
03933 }
03934
03935 break;
03936 }
03937
03938 case GSF_HOUSES:
03939 case GSF_AIRPORTTILES:
03940 case GSF_OBJECTS:
03941 case GSF_INDUSTRYTILES: {
03942 byte num_spriteset_ents = _cur_grffile->spriteset_numents;
03943 byte num_spritesets = _cur_grffile->spriteset_numsets;
03944 byte num_building_sprites = max((uint8)1, type);
03945 uint i;
03946
03947 assert(TileLayoutSpriteGroup::CanAllocateItem());
03948 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
03949 act_group = group;
03950
03951 group->num_building_stages = max((uint8)1, num_spriteset_ents);
03952 group->dts = CallocT<DrawTileSprites>(1);
03953
03954
03955 group->dts->ground.sprite = buf->ReadWord();
03956 group->dts->ground.pal = buf->ReadWord();
03957
03958
03959 MapSpriteMappingRecolour(&group->dts->ground);
03960
03961 if (HasBit(group->dts->ground.pal, 15)) {
03962
03963
03964 uint spriteset = GB(group->dts->ground.sprite, 0, 14);
03965 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03966 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03967 group->dts->ground.sprite = SPR_IMG_QUERY;
03968 group->dts->ground.pal = PAL_NONE;
03969 } else {
03970 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03971 SB(group->dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
03972 ClrBit(group->dts->ground.pal, 15);
03973 SetBit(group->dts->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
03974 }
03975 }
03976
03977 group->dts->seq = CallocT<DrawTileSeqStruct>(num_building_sprites + 1);
03978
03979 for (i = 0; i < num_building_sprites; i++) {
03980 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&group->dts->seq[i]);
03981
03982 seq->image.sprite = buf->ReadWord();
03983 seq->image.pal = buf->ReadWord();
03984 seq->delta_x = buf->ReadByte();
03985 seq->delta_y = buf->ReadByte();
03986
03987 MapSpriteMappingRecolour(&seq->image);
03988
03989 if (HasBit(seq->image.pal, 15)) {
03990
03991
03992 uint spriteset = GB(seq->image.sprite, 0, 14);
03993 if (num_spriteset_ents == 0 || spriteset >= num_spritesets) {
03994 grfmsg(1, "NewSpriteGroup: Spritelayout uses undefined custom spriteset %d", spriteset);
03995 seq->image.sprite = SPR_IMG_QUERY;
03996 seq->image.pal = PAL_NONE;
03997 } else {
03998 SpriteID sprite = _cur_grffile->spriteset_start + spriteset * num_spriteset_ents;
03999 SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
04000 ClrBit(seq->image.pal, 15);
04001 SetBit(seq->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
04002 }
04003 }
04004
04005 if (type > 0) {
04006 seq->delta_z = buf->ReadByte();
04007 if ((byte)seq->delta_z == 0x80) continue;
04008 }
04009
04010 seq->size_x = buf->ReadByte();
04011 seq->size_y = buf->ReadByte();
04012 seq->size_z = buf->ReadByte();
04013 }
04014
04015
04016 const_cast<DrawTileSeqStruct *>(group->dts->seq)[i].delta_x = (int8)0x80;
04017
04018 break;
04019 }
04020
04021 case GSF_INDUSTRIES: {
04022 if (type > 1) {
04023 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
04024 break;
04025 }
04026
04027 assert(IndustryProductionSpriteGroup::CanAllocateItem());
04028 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
04029 act_group = group;
04030 group->version = type;
04031 if (type == 0) {
04032 for (uint i = 0; i < 3; i++) {
04033 group->subtract_input[i] = (int16)buf->ReadWord();
04034 }
04035 for (uint i = 0; i < 2; i++) {
04036 group->add_output[i] = buf->ReadWord();
04037 }
04038 group->again = buf->ReadByte();
04039 } else {
04040 for (uint i = 0; i < 3; i++) {
04041 group->subtract_input[i] = buf->ReadByte();
04042 }
04043 for (uint i = 0; i < 2; i++) {
04044 group->add_output[i] = buf->ReadByte();
04045 }
04046 group->again = buf->ReadByte();
04047 }
04048 break;
04049 }
04050
04051
04052 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
04053 }
04054 }
04055 }
04056
04057 _cur_grffile->spritegroups[setid] = act_group;
04058 }
04059
04060 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
04061 {
04062 if (feature == GSF_OBJECTS) {
04063 switch (ctype) {
04064 case 0: return 0;
04065 case 0xFF: return CT_PURCHASE_OBJECT;
04066 default:
04067 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
04068 return CT_INVALID;
04069 }
04070 }
04071
04072 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
04073 if (ctype == 0xFF) return CT_PURCHASE;
04074
04075 if (_cur_grffile->cargo_max == 0) {
04076
04077 if (ctype >= 32) {
04078 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
04079 return CT_INVALID;
04080 }
04081
04082 const CargoSpec *cs;
04083 FOR_ALL_CARGOSPECS(cs) {
04084 if (cs->bitnum == ctype) {
04085 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
04086 return cs->Index();
04087 }
04088 }
04089
04090 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
04091 return CT_INVALID;
04092 }
04093
04094
04095 if (ctype >= _cur_grffile->cargo_max) {
04096 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
04097 return CT_INVALID;
04098 }
04099
04100
04101 CargoLabel cl = _cur_grffile->cargo_list[ctype];
04102 if (cl == 0) {
04103 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
04104 return CT_INVALID;
04105 }
04106
04107 ctype = GetCargoIDByLabel(cl);
04108 if (ctype == CT_INVALID) {
04109 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));
04110 return CT_INVALID;
04111 }
04112
04113 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);
04114 return ctype;
04115 }
04116
04117
04118 static bool IsValidGroupID(uint16 groupid, const char *function)
04119 {
04120 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
04121 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
04122 return false;
04123 }
04124
04125 return true;
04126 }
04127
04128 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
04129 {
04130 static EngineID *last_engines;
04131 static uint last_engines_count;
04132 bool wagover = false;
04133
04134
04135 if (HasBit(idcount, 7)) {
04136 wagover = true;
04137
04138 idcount = GB(idcount, 0, 7);
04139
04140 if (last_engines_count == 0) {
04141 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
04142 return;
04143 }
04144
04145 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
04146 last_engines_count, idcount);
04147 } else {
04148 if (last_engines_count != idcount) {
04149 last_engines = ReallocT(last_engines, idcount);
04150 last_engines_count = idcount;
04151 }
04152 }
04153
04154 EngineID *engines = AllocaM(EngineID, idcount);
04155 for (uint i = 0; i < idcount; i++) {
04156 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, buf->ReadExtendedByte());
04157 if (e == NULL) {
04158
04159
04160
04161 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
04162 return;
04163 }
04164
04165 engines[i] = e->index;
04166 if (!wagover) last_engines[i] = engines[i];
04167 }
04168
04169 uint8 cidcount = buf->ReadByte();
04170 for (uint c = 0; c < cidcount; c++) {
04171 uint8 ctype = buf->ReadByte();
04172 uint16 groupid = buf->ReadWord();
04173 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
04174
04175 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
04176
04177 ctype = TranslateCargo(feature, ctype);
04178 if (ctype == CT_INVALID) continue;
04179
04180 for (uint i = 0; i < idcount; i++) {
04181 EngineID engine = engines[i];
04182
04183 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
04184
04185 if (wagover) {
04186 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
04187 } else {
04188 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
04189 }
04190 }
04191 }
04192
04193 uint16 groupid = buf->ReadWord();
04194 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
04195
04196 grfmsg(8, "-- Default group id 0x%04X", groupid);
04197
04198 for (uint i = 0; i < idcount; i++) {
04199 EngineID engine = engines[i];
04200
04201 if (wagover) {
04202 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
04203 } else {
04204 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
04205 SetEngineGRF(engine, _cur_grffile);
04206 }
04207 }
04208 }
04209
04210
04211 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
04212 {
04213 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
04214 for (uint i = 0; i < idcount; i++) {
04215 cfs[i] = (CanalFeature)buf->ReadByte();
04216 }
04217
04218 uint8 cidcount = buf->ReadByte();
04219 buf->Skip(cidcount * 3);
04220
04221 uint16 groupid = buf->ReadWord();
04222 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
04223
04224 for (uint i = 0; i < idcount; i++) {
04225 CanalFeature cf = cfs[i];
04226
04227 if (cf >= CF_END) {
04228 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
04229 continue;
04230 }
04231
04232 _water_feature[cf].grffile = _cur_grffile;
04233 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
04234 }
04235 }
04236
04237
04238 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
04239 {
04240 uint8 *stations = AllocaM(uint8, idcount);
04241 for (uint i = 0; i < idcount; i++) {
04242 stations[i] = buf->ReadByte();
04243 }
04244
04245 uint8 cidcount = buf->ReadByte();
04246 for (uint c = 0; c < cidcount; c++) {
04247 uint8 ctype = buf->ReadByte();
04248 uint16 groupid = buf->ReadWord();
04249 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
04250
04251 ctype = TranslateCargo(GSF_STATIONS, ctype);
04252 if (ctype == CT_INVALID) continue;
04253
04254 for (uint i = 0; i < idcount; i++) {
04255 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
04256
04257 if (statspec == NULL) {
04258 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04259 continue;
04260 }
04261
04262 statspec->grf_prop.spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
04263 }
04264 }
04265
04266 uint16 groupid = buf->ReadWord();
04267 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
04268
04269 for (uint i = 0; i < idcount; i++) {
04270 StationSpec *statspec = _cur_grffile->stations == NULL ? NULL : _cur_grffile->stations[stations[i]];
04271
04272 if (statspec == NULL) {
04273 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
04274 continue;
04275 }
04276
04277 if (statspec->grf_prop.grffile != NULL) {
04278 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
04279 continue;
04280 }
04281
04282 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
04283 statspec->grf_prop.grffile = _cur_grffile;
04284 statspec->grf_prop.local_id = stations[i];
04285 StationClass::Assign(statspec);
04286 }
04287 }
04288
04289
04290 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
04291 {
04292 uint8 *houses = AllocaM(uint8, idcount);
04293 for (uint i = 0; i < idcount; i++) {
04294 houses[i] = buf->ReadByte();
04295 }
04296
04297
04298 uint8 cidcount = buf->ReadByte();
04299 buf->Skip(cidcount * 3);
04300
04301 uint16 groupid = buf->ReadWord();
04302 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
04303
04304 if (_cur_grffile->housespec == NULL) {
04305 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
04306 return;
04307 }
04308
04309 for (uint i = 0; i < idcount; i++) {
04310 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
04311
04312 if (hs == NULL) {
04313 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
04314 continue;
04315 }
04316
04317 hs->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04318 }
04319 }
04320
04321 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
04322 {
04323 uint8 *industries = AllocaM(uint8, idcount);
04324 for (uint i = 0; i < idcount; i++) {
04325 industries[i] = buf->ReadByte();
04326 }
04327
04328
04329 uint8 cidcount = buf->ReadByte();
04330 buf->Skip(cidcount * 3);
04331
04332 uint16 groupid = buf->ReadWord();
04333 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
04334
04335 if (_cur_grffile->industryspec == NULL) {
04336 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
04337 return;
04338 }
04339
04340 for (uint i = 0; i < idcount; i++) {
04341 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
04342
04343 if (indsp == NULL) {
04344 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
04345 continue;
04346 }
04347
04348 indsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04349 }
04350 }
04351
04352 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04353 {
04354 uint8 *indtiles = AllocaM(uint8, idcount);
04355 for (uint i = 0; i < idcount; i++) {
04356 indtiles[i] = buf->ReadByte();
04357 }
04358
04359
04360 uint8 cidcount = buf->ReadByte();
04361 buf->Skip(cidcount * 3);
04362
04363 uint16 groupid = buf->ReadWord();
04364 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
04365
04366 if (_cur_grffile->indtspec == NULL) {
04367 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
04368 return;
04369 }
04370
04371 for (uint i = 0; i < idcount; i++) {
04372 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
04373
04374 if (indtsp == NULL) {
04375 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
04376 continue;
04377 }
04378
04379 indtsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04380 }
04381 }
04382
04383 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
04384 {
04385 CargoID *cargos = AllocaM(CargoID, idcount);
04386 for (uint i = 0; i < idcount; i++) {
04387 cargos[i] = buf->ReadByte();
04388 }
04389
04390
04391 uint8 cidcount = buf->ReadByte();
04392 buf->Skip(cidcount * 3);
04393
04394 uint16 groupid = buf->ReadWord();
04395 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
04396
04397 for (uint i = 0; i < idcount; i++) {
04398 CargoID cid = cargos[i];
04399
04400 if (cid >= NUM_CARGO) {
04401 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
04402 continue;
04403 }
04404
04405 CargoSpec *cs = CargoSpec::Get(cid);
04406 cs->grffile = _cur_grffile;
04407 cs->group = _cur_grffile->spritegroups[groupid];
04408 }
04409 }
04410
04411 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
04412 {
04413 if (_cur_grffile->objectspec == NULL) {
04414 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
04415 return;
04416 }
04417
04418 uint8 *objects = AllocaM(uint8, idcount);
04419 for (uint i = 0; i < idcount; i++) {
04420 objects[i] = buf->ReadByte();
04421 }
04422
04423 uint8 cidcount = buf->ReadByte();
04424 for (uint c = 0; c < cidcount; c++) {
04425 uint8 ctype = buf->ReadByte();
04426 uint16 groupid = buf->ReadWord();
04427 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
04428
04429 ctype = TranslateCargo(GSF_OBJECTS, ctype);
04430 if (ctype == CT_INVALID) continue;
04431
04432 for (uint i = 0; i < idcount; i++) {
04433 ObjectSpec *spec = _cur_grffile->objectspec[objects[i]];
04434
04435 if (spec == NULL) {
04436 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04437 continue;
04438 }
04439
04440 spec->grf_prop.spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
04441 }
04442 }
04443
04444 uint16 groupid = buf->ReadWord();
04445 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
04446
04447 for (uint i = 0; i < idcount; i++) {
04448 ObjectSpec *spec = _cur_grffile->objectspec[objects[i]];
04449
04450 if (spec == NULL) {
04451 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
04452 continue;
04453 }
04454
04455 if (spec->grf_prop.grffile != NULL) {
04456 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
04457 continue;
04458 }
04459
04460 spec->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04461 spec->grf_prop.grffile = _cur_grffile;
04462 spec->grf_prop.local_id = objects[i];
04463 }
04464 }
04465
04466 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
04467 {
04468 uint8 *railtypes = AllocaM(uint8, idcount);
04469 for (uint i = 0; i < idcount; i++) {
04470 railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
04471 }
04472
04473 uint8 cidcount = buf->ReadByte();
04474 for (uint c = 0; c < cidcount; c++) {
04475 uint8 ctype = buf->ReadByte();
04476 uint16 groupid = buf->ReadWord();
04477 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
04478
04479 if (ctype >= RTSG_END) continue;
04480
04481 extern RailtypeInfo _railtypes[RAILTYPE_END];
04482 for (uint i = 0; i < idcount; i++) {
04483 if (railtypes[i] != INVALID_RAILTYPE) {
04484 RailtypeInfo *rti = &_railtypes[railtypes[i]];
04485
04486 rti->grffile[ctype] = _cur_grffile;
04487 rti->group[ctype] = _cur_grffile->spritegroups[groupid];
04488 }
04489 }
04490 }
04491
04492
04493 buf->ReadWord();
04494 }
04495
04496 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
04497 {
04498 uint8 *airports = AllocaM(uint8, idcount);
04499 for (uint i = 0; i < idcount; i++) {
04500 airports[i] = buf->ReadByte();
04501 }
04502
04503
04504 uint8 cidcount = buf->ReadByte();
04505 buf->Skip(cidcount * 3);
04506
04507 uint16 groupid = buf->ReadWord();
04508 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
04509
04510 if (_cur_grffile->airportspec == NULL) {
04511 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
04512 return;
04513 }
04514
04515 for (uint i = 0; i < idcount; i++) {
04516 AirportSpec *as = _cur_grffile->airportspec[airports[i]];
04517
04518 if (as == NULL) {
04519 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
04520 continue;
04521 }
04522
04523 as->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04524 }
04525 }
04526
04527 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
04528 {
04529 uint8 *airptiles = AllocaM(uint8, idcount);
04530 for (uint i = 0; i < idcount; i++) {
04531 airptiles[i] = buf->ReadByte();
04532 }
04533
04534
04535 uint8 cidcount = buf->ReadByte();
04536 buf->Skip(cidcount * 3);
04537
04538 uint16 groupid = buf->ReadWord();
04539 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
04540
04541 if (_cur_grffile->airtspec == NULL) {
04542 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
04543 return;
04544 }
04545
04546 for (uint i = 0; i < idcount; i++) {
04547 AirportTileSpec *airtsp = _cur_grffile->airtspec[airptiles[i]];
04548
04549 if (airtsp == NULL) {
04550 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
04551 continue;
04552 }
04553
04554 airtsp->grf_prop.spritegroup[0] = _cur_grffile->spritegroups[groupid];
04555 }
04556 }
04557
04558
04559
04560 static void FeatureMapSpriteGroup(ByteReader *buf)
04561 {
04562
04563
04564
04565
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576 if (_cur_grffile->spritegroups == NULL) {
04577 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
04578 return;
04579 }
04580
04581 uint8 feature = buf->ReadByte();
04582 uint8 idcount = buf->ReadByte();
04583
04584
04585 if (idcount == 0) {
04586
04587 buf->ReadByte();
04588 uint16 groupid = buf->ReadWord();
04589 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
04590
04591 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
04592
04593 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
04594 return;
04595 }
04596
04597
04598 SetBit(_cur_grffile->grf_features, feature);
04599
04600 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
04601
04602 switch (feature) {
04603 case GSF_TRAINS:
04604 case GSF_ROADVEHICLES:
04605 case GSF_SHIPS:
04606 case GSF_AIRCRAFT:
04607 VehicleMapSpriteGroup(buf, feature, idcount);
04608 return;
04609
04610 case GSF_CANALS:
04611 CanalMapSpriteGroup(buf, idcount);
04612 return;
04613
04614 case GSF_STATIONS:
04615 StationMapSpriteGroup(buf, idcount);
04616 return;
04617
04618 case GSF_HOUSES:
04619 TownHouseMapSpriteGroup(buf, idcount);
04620 return;
04621
04622 case GSF_INDUSTRIES:
04623 IndustryMapSpriteGroup(buf, idcount);
04624 return;
04625
04626 case GSF_INDUSTRYTILES:
04627 IndustrytileMapSpriteGroup(buf, idcount);
04628 return;
04629
04630 case GSF_CARGOS:
04631 CargoMapSpriteGroup(buf, idcount);
04632 return;
04633
04634 case GSF_AIRPORTS:
04635 AirportMapSpriteGroup(buf, idcount);
04636 return;
04637
04638 case GSF_OBJECTS:
04639 ObjectMapSpriteGroup(buf, idcount);
04640 break;
04641
04642 case GSF_RAILTYPES:
04643 RailTypeMapSpriteGroup(buf, idcount);
04644 break;
04645
04646 case GSF_AIRPORTTILES:
04647 AirportTileMapSpriteGroup(buf, idcount);
04648 return;
04649
04650 default:
04651 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
04652 return;
04653 }
04654 }
04655
04656
04657 static void FeatureNewName(ByteReader *buf)
04658 {
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672
04673
04674
04675 bool new_scheme = _cur_grffile->grf_version >= 7;
04676
04677 uint8 feature = buf->ReadByte();
04678 uint8 lang = buf->ReadByte();
04679 uint8 num = buf->ReadByte();
04680 bool generic = HasBit(lang, 7);
04681 uint16 id;
04682 if (generic) {
04683 id = buf->ReadWord();
04684 } else if (feature <= GSF_AIRCRAFT) {
04685 id = buf->ReadExtendedByte();
04686 } else {
04687 id = buf->ReadByte();
04688 }
04689
04690 ClrBit(lang, 7);
04691
04692 uint16 endid = id + num;
04693
04694 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
04695 id, endid, feature, lang);
04696
04697 for (; id < endid && buf->HasData(); id++) {
04698 const char *name = buf->ReadString();
04699 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
04700
04701 switch (feature) {
04702 case GSF_TRAINS:
04703 case GSF_ROADVEHICLES:
04704 case GSF_SHIPS:
04705 case GSF_AIRCRAFT:
04706 if (!generic) {
04707 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
04708 if (e == NULL) break;
04709 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
04710 e->info.string_id = string;
04711 } else {
04712 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
04713 }
04714 break;
04715
04716 case GSF_INDUSTRIES: {
04717 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
04718 break;
04719 }
04720
04721 case GSF_HOUSES:
04722 default:
04723 switch (GB(id, 8, 8)) {
04724 case 0xC4:
04725 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04726 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04727 } else {
04728 StationClassID cls_id = _cur_grffile->stations[GB(id, 0, 8)]->cls_id;
04729 StationClass::SetName(cls_id, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED));
04730 }
04731 break;
04732
04733 case 0xC5:
04734 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
04735 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
04736 } else {
04737 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
04738 }
04739 break;
04740
04741 case 0xC7:
04742 if (_cur_grffile->airtspec == NULL || _cur_grffile->airtspec[GB(id, 0, 8)] == NULL) {
04743 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
04744 } else {
04745 _cur_grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
04746 }
04747 break;
04748
04749 case 0xC9:
04750 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
04751 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
04752 } else {
04753 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
04754 }
04755 break;
04756
04757 case 0xD0:
04758 case 0xD1:
04759 case 0xD2:
04760 case 0xD3:
04761 case 0xDC:
04762 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
04763 break;
04764
04765 default:
04766 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
04767 break;
04768 }
04769 break;
04770 }
04771 }
04772 }
04773
04782 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
04783 {
04784
04785 if (offset >= max_sprites) {
04786 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
04787 uint orig_num = num;
04788 num = 0;
04789 return orig_num;
04790 }
04791
04792 if (offset + num > max_sprites) {
04793 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
04794 uint orig_num = num;
04795 num = max(max_sprites - offset, 0);
04796 return orig_num - num;
04797 }
04798
04799 return 0;
04800 }
04801
04802
04804 enum Action5BlockType {
04805 A5BLOCK_FIXED,
04806 A5BLOCK_ALLOW_OFFSET,
04807 A5BLOCK_INVALID,
04808 };
04810 struct Action5Type {
04811 Action5BlockType block_type;
04812 SpriteID sprite_base;
04813 uint16 min_sprites;
04814 uint16 max_sprites;
04815 const char *name;
04816 };
04817
04819 static const Action5Type _action5_types[] = {
04820
04821 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
04822 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
04823 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
04824 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
04825 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
04826 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
04827 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
04828 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
04829 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
04830 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
04831 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
04832 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
04833 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
04834 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
04835 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
04836 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
04837 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
04838 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
04839 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
04840 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
04841 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
04842 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
04843 { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
04844 };
04845
04846
04847 static void GraphicsNew(ByteReader *buf)
04848 {
04849
04850
04851
04852
04853
04854
04855
04856 uint8 type = buf->ReadByte();
04857 uint16 num = buf->ReadExtendedByte();
04858 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
04859 ClrBit(type, 7);
04860
04861 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
04862
04863
04864 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
04865 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
04866 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
04867 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
04868 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
04869 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
04870 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
04871 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
04872 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
04873 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
04874 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
04875 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
04876 return;
04877 }
04878
04879
04880 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
04881 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
04882 _skip_sprites = num;
04883 return;
04884 }
04885
04886 const Action5Type *action5_type = &_action5_types[type];
04887
04888
04889 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
04890 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
04891 offset = 0;
04892 }
04893
04894
04895
04896 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
04897 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);
04898 _skip_sprites = num;
04899 return;
04900 }
04901
04902
04903 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
04904 SpriteID replace = action5_type->sprite_base + offset;
04905
04906
04907 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);
04908
04909 for (; num > 0; num--) {
04910 _nfo_line++;
04911 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
04912 }
04913
04914 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
04915
04916 _skip_sprites = skip_num;
04917 }
04918
04919
04920 static void SkipAct5(ByteReader *buf)
04921 {
04922
04923 buf->ReadByte();
04924
04925
04926 _skip_sprites = buf->ReadExtendedByte();
04927
04928 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
04929 }
04930
04936 void CheckForMissingSprites()
04937 {
04938
04939
04940 bool missing = false;
04941 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
04942 const Action5Type *type = &_action5_types[i];
04943 if (type->block_type == A5BLOCK_INVALID) continue;
04944
04945 for (uint j = 0; j < type->max_sprites; j++) {
04946 if (!SpriteExists(type->sprite_base + j)) {
04947 DEBUG(grf, 0, "%s sprites are missing", type->name);
04948 missing = true;
04949
04950 break;
04951 }
04952 }
04953 }
04954
04955 if (missing) {
04956 ShowErrorMessage(STR_NEWGRF_ERROR_MISSING_SPRITES, INVALID_STRING_ID, WL_CRITICAL);
04957 }
04958 }
04959
04970 bool GetGlobalVariable(byte param, uint32 *value)
04971 {
04972 switch (param) {
04973 case 0x00:
04974 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
04975 return true;
04976
04977 case 0x01:
04978 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
04979 return true;
04980
04981 case 0x02: {
04982 YearMonthDay ymd;
04983 ConvertDateToYMD(_date, &ymd);
04984 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
04985 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
04986 return true;
04987 }
04988
04989 case 0x03:
04990 *value = _settings_game.game_creation.landscape;
04991 return true;
04992
04993 case 0x06:
04994 *value = _settings_game.vehicle.road_side << 4;
04995 return true;
04996
04997 case 0x09:
04998 *value = _date_fract * 885;
04999 return true;
05000
05001 case 0x0A:
05002 *value = _tick_counter;
05003 return true;
05004
05005 case 0x0B: {
05006 uint major = 2;
05007 uint minor = 6;
05008 uint revision = 1;
05009 uint build = 1382;
05010 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
05011 return true;
05012 }
05013
05014 case 0x0D:
05015 *value = _cur_grfconfig->palette & GRFP_USE_MASK;
05016 return true;
05017
05018 case 0x0E:
05019 *value = _cur_grffile->traininfo_vehicle_pitch;
05020 return true;
05021
05022 case 0x0F:
05023 *value = 0;
05024 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
05025 if (_settings_game.vehicle.disable_elrails) {
05026
05027 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
05028 } else {
05029 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
05030
05031 }
05032 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
05033 return true;
05034
05035 case 0x11:
05036 *value = 0;
05037 return true;
05038
05039 case 0x12:
05040 *value = _game_mode;
05041 return true;
05042
05043
05044
05045
05046
05047
05048
05049 case 0x1A:
05050 *value = UINT_MAX;
05051 return true;
05052
05053 case 0x1B:
05054 *value = 0x3F;
05055 return true;
05056
05057 case 0x1D:
05058 *value = 1;
05059 return true;
05060
05061 case 0x1E:
05062 *value = _misc_grf_features;
05063
05064
05065 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
05066 if (_cur_grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
05067 return true;
05068
05069
05070
05071 case 0x20:
05072 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
05073 return true;
05074
05075 case 0x21:
05076 *value = _openttd_newgrf_version;
05077 return true;
05078
05079 case 0x22:
05080 *value = _settings_game.difficulty.diff_level;
05081 return true;
05082
05083 case 0x23:
05084 *value = _date;
05085 return true;
05086
05087 case 0x24:
05088 *value = _cur_year;
05089 return true;
05090
05091 default: return false;
05092 }
05093 }
05094
05095 static uint32 GetParamVal(byte param, uint32 *cond_val)
05096 {
05097
05098 uint32 value;
05099 if (GetGlobalVariable(param - 0x80, &value)) return value;
05100
05101
05102 switch (param) {
05103 case 0x84: {
05104 uint32 res = 0;
05105
05106 if (_cur_stage > GLS_INIT) SetBit(res, 0);
05107 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
05108 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
05109 return res;
05110 }
05111
05112 case 0x85:
05113 if (cond_val == NULL) {
05114
05115 return 0;
05116 } else {
05117 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
05118 *cond_val %= 0x20;
05119 return param_val;
05120 }
05121
05122 case 0x88:
05123 return 0;
05124
05125
05126
05127 default:
05128
05129 if (param < 0x80) return _cur_grffile->GetParam(param);
05130
05131
05132 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
05133 return UINT_MAX;
05134 }
05135 }
05136
05137
05138 static void CfgApply(ByteReader *buf)
05139 {
05140
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151
05152 size_t pos = FioGetPos();
05153 uint16 num = FioReadWord();
05154 uint8 type = FioReadByte();
05155 byte *preload_sprite = NULL;
05156
05157
05158 if (type == 0xFF) {
05159 preload_sprite = MallocT<byte>(num);
05160 FioReadBlock(preload_sprite, num);
05161 }
05162
05163
05164 FioSeekTo(pos, SEEK_SET);
05165
05166 if (type != 0xFF) {
05167 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
05168 free(preload_sprite);
05169 return;
05170 }
05171
05172 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line + 1);
05173 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
05174 if (it != _grf_line_to_action6_sprite_override.end()) {
05175 free(preload_sprite);
05176 preload_sprite = _grf_line_to_action6_sprite_override[location];
05177 } else {
05178 _grf_line_to_action6_sprite_override[location] = preload_sprite;
05179 }
05180
05181
05182
05183 for (;;) {
05184 uint i;
05185 uint param_num;
05186 uint param_size;
05187 uint offset;
05188 bool add_value;
05189
05190
05191 param_num = buf->ReadByte();
05192 if (param_num == 0xFF) break;
05193
05194
05195
05196 param_size = buf->ReadByte();
05197
05198
05199
05200 add_value = HasBit(param_size, 7);
05201 param_size = GB(param_size, 0, 7);
05202
05203
05204 offset = buf->ReadExtendedByte();
05205
05206
05207
05208 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
05209 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
05210 break;
05211 }
05212
05213 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
05214
05215 bool carry = false;
05216 for (i = 0; i < param_size && offset + i < num; i++) {
05217 uint32 value = GetParamVal(param_num + i / 4, NULL);
05218
05219
05220 if (i % 4 == 0) carry = false;
05221
05222 if (add_value) {
05223 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
05224 preload_sprite[offset + i] = GB(new_value, 0, 8);
05225
05226 carry = new_value >= 256;
05227 } else {
05228 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
05229 }
05230 }
05231 }
05232 }
05233
05243 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
05244 {
05245 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
05246 error->data = strdup(_cur_grfconfig->GetName());
05247 }
05248
05249
05250
05251 static void SkipIf(ByteReader *buf)
05252 {
05253
05254
05255
05256
05257
05258
05259
05260
05261 uint32 cond_val = 0;
05262 uint32 mask = 0;
05263 bool result;
05264
05265 uint8 param = buf->ReadByte();
05266 uint8 paramsize = buf->ReadByte();
05267 uint8 condtype = buf->ReadByte();
05268
05269 if (condtype < 2) {
05270
05271 paramsize = 1;
05272 }
05273
05274 switch (paramsize) {
05275 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
05276 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
05277 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
05278 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
05279 default: break;
05280 }
05281
05282 if (param < 0x80 && _cur_grffile->param_end <= param) {
05283 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
05284 return;
05285 }
05286
05287 uint32 param_val = GetParamVal(param, &cond_val);
05288
05289 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
05290
05291
05292
05293
05294
05295
05296
05297
05298
05299 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
05300
05301
05302 GRFConfig *c = GetGRFConfig(cond_val, mask);
05303
05304 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05305 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05306 c = NULL;
05307 }
05308
05309 if (condtype != 10 && c == NULL) {
05310 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
05311 return;
05312 }
05313
05314 switch (condtype) {
05315
05316 case 0x06:
05317 result = c->status == GCS_ACTIVATED;
05318 break;
05319
05320 case 0x07:
05321 result = c->status != GCS_ACTIVATED;
05322 break;
05323
05324 case 0x08:
05325 result = c->status == GCS_INITIALISED;
05326 break;
05327
05328 case 0x09:
05329 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
05330 break;
05331
05332 case 0x0A:
05333
05334 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
05335 break;
05336
05337 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
05338 }
05339 } else {
05340
05341 switch (condtype) {
05342 case 0x00: result = !!(param_val & (1 << cond_val));
05343 break;
05344 case 0x01: result = !(param_val & (1 << cond_val));
05345 break;
05346 case 0x02: result = (param_val & mask) == cond_val;
05347 break;
05348 case 0x03: result = (param_val & mask) != cond_val;
05349 break;
05350 case 0x04: result = (param_val & mask) < cond_val;
05351 break;
05352 case 0x05: result = (param_val & mask) > cond_val;
05353 break;
05354 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
05355 break;
05356 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
05357 break;
05358 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
05359 break;
05360 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
05361 break;
05362
05363 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
05364 }
05365 }
05366
05367 if (!result) {
05368 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
05369 return;
05370 }
05371
05372 uint8 numsprites = buf->ReadByte();
05373
05374
05375
05376
05377
05378 GRFLabel *choice = NULL;
05379 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
05380 if (label->label != numsprites) continue;
05381
05382
05383 if (choice == NULL) choice = label;
05384
05385 if (label->nfo_line > _nfo_line) {
05386 choice = label;
05387 break;
05388 }
05389 }
05390
05391 if (choice != NULL) {
05392 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
05393 FioSeekTo(choice->pos, SEEK_SET);
05394 _nfo_line = choice->nfo_line;
05395 return;
05396 }
05397
05398 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
05399 _skip_sprites = numsprites;
05400 if (_skip_sprites == 0) {
05401
05402
05403
05404 _skip_sprites = -1;
05405
05406
05407 if (_cur_grfconfig->status != (_cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
05408 DisableGrf();
05409 }
05410 }
05411 }
05412
05413
05414
05415 static void ScanInfo(ByteReader *buf)
05416 {
05417 uint8 grf_version = buf->ReadByte();
05418 uint32 grfid = buf->ReadDWord();
05419 const char *name = buf->ReadString();
05420
05421 _cur_grfconfig->ident.grfid = grfid;
05422
05423
05424 if (grf_version > 7) {
05425 SetBit(_cur_grfconfig->flags, GCF_INVALID);
05426 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);
05427 }
05428
05429
05430 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
05431
05432 AddGRFTextToList(&_cur_grfconfig->name->text, 0x7F, grfid, false, name);
05433
05434 if (buf->HasData()) {
05435 const char *info = buf->ReadString();
05436 AddGRFTextToList(&_cur_grfconfig->info->text, 0x7F, grfid, true, info);
05437 }
05438
05439
05440 _skip_sprites = -1;
05441 }
05442
05443
05444 static void GRFInfo(ByteReader *buf)
05445 {
05446
05447
05448
05449
05450
05451
05452
05453 uint8 version = buf->ReadByte();
05454 uint32 grfid = buf->ReadDWord();
05455 const char *name = buf->ReadString();
05456
05457 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
05458 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
05459 return;
05460 }
05461
05462 if (_cur_grffile->grfid != grfid) {
05463 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));
05464 _cur_grffile->grfid = grfid;
05465 }
05466
05467 _cur_grffile->grf_version = version;
05468 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
05469
05470
05471 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);
05472 }
05473
05474
05475 static void SpriteReplace(ByteReader *buf)
05476 {
05477
05478
05479
05480
05481
05482
05483
05484
05485 uint8 num_sets = buf->ReadByte();
05486
05487 for (uint i = 0; i < num_sets; i++) {
05488 uint8 num_sprites = buf->ReadByte();
05489 uint16 first_sprite = buf->ReadWord();
05490
05491 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
05492 i, num_sprites, first_sprite
05493 );
05494
05495 for (uint j = 0; j < num_sprites; j++) {
05496 int load_index = first_sprite + j;
05497 _nfo_line++;
05498 LoadNextSprite(load_index, _file_index, _nfo_line);
05499
05500
05501
05502 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
05503 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
05504 }
05505 }
05506 }
05507 }
05508
05509
05510 static void SkipActA(ByteReader *buf)
05511 {
05512 uint8 num_sets = buf->ReadByte();
05513
05514 for (uint i = 0; i < num_sets; i++) {
05515
05516 _skip_sprites += buf->ReadByte();
05517
05518 buf->ReadWord();
05519 }
05520
05521 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
05522 }
05523
05524
05525 static void GRFLoadError(ByteReader *buf)
05526 {
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542 static const StringID msgstr[] = {
05543 STR_NEWGRF_ERROR_VERSION_NUMBER,
05544 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
05545 STR_NEWGRF_ERROR_UNSET_SWITCH,
05546 STR_NEWGRF_ERROR_INVALID_PARAMETER,
05547 STR_NEWGRF_ERROR_LOAD_BEFORE,
05548 STR_NEWGRF_ERROR_LOAD_AFTER,
05549 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
05550 };
05551
05552 static const StringID sevstr[] = {
05553 STR_NEWGRF_ERROR_MSG_INFO,
05554 STR_NEWGRF_ERROR_MSG_WARNING,
05555 STR_NEWGRF_ERROR_MSG_ERROR,
05556 STR_NEWGRF_ERROR_MSG_FATAL
05557 };
05558
05559
05560 if (_cur_grfconfig->error != NULL) return;
05561
05562 byte severity = buf->ReadByte();
05563 byte lang = buf->ReadByte();
05564 byte message_id = buf->ReadByte();
05565
05566
05567 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
05568
05569
05570
05571 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
05572 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
05573 return;
05574 }
05575 ClrBit(severity, 7);
05576
05577 if (severity >= lengthof(sevstr)) {
05578 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
05579 severity = 2;
05580 } else if (severity == 3) {
05581
05582
05583 DisableGrf();
05584 }
05585
05586 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
05587 grfmsg(7, "GRFLoadError: Invalid message id.");
05588 return;
05589 }
05590
05591 if (buf->Remaining() <= 1) {
05592 grfmsg(7, "GRFLoadError: No message data supplied.");
05593 return;
05594 }
05595
05596 GRFError *error = new GRFError(sevstr[severity]);
05597
05598 if (message_id == 0xFF) {
05599
05600 if (buf->HasData()) {
05601 const char *message = buf->ReadString();
05602
05603 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, true, message);
05604 } else {
05605 grfmsg(7, "GRFLoadError: No custom message supplied.");
05606 error->custom_message = strdup("");
05607 }
05608 } else {
05609 error->message = msgstr[message_id];
05610 }
05611
05612 if (buf->HasData()) {
05613 const char *data = buf->ReadString();
05614
05615 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, lang, true, data);
05616 } else {
05617 grfmsg(7, "GRFLoadError: No message data supplied.");
05618 error->data = strdup("");
05619 }
05620
05621
05622 uint i = 0;
05623 for (; i < 2 && buf->HasData(); i++) {
05624 uint param_number = buf->ReadByte();
05625 error->param_value[i] = _cur_grffile->GetParam(param_number);
05626 }
05627 error->num_params = i;
05628
05629 _cur_grfconfig->error = error;
05630 }
05631
05632
05633 static void GRFComment(ByteReader *buf)
05634 {
05635
05636
05637
05638
05639 if (!buf->HasData()) return;
05640
05641 const char *text = buf->ReadString();
05642 grfmsg(2, "GRFComment: %s", text);
05643 }
05644
05645
05646 static void SafeParamSet(ByteReader *buf)
05647 {
05648 uint8 target = buf->ReadByte();
05649
05650
05651 if (target < 0x80) return;
05652
05653
05654
05655
05656
05657
05658 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05659
05660
05661 _skip_sprites = -1;
05662 }
05663
05664
05665 static uint32 GetPatchVariable(uint8 param)
05666 {
05667 switch (param) {
05668
05669 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
05670
05671
05672 case 0x0E: return _settings_game.vehicle.freight_trains;
05673
05674
05675 case 0x0F: return 0;
05676
05677
05678
05679
05680 case 0x10:
05681 switch (_settings_game.vehicle.plane_speed) {
05682 default:
05683 case 4: return 1;
05684 case 3: return 2;
05685 case 2: return 2;
05686 case 1: return 4;
05687 }
05688
05689
05690
05691 case 0x11: return SPR_2CCMAP_BASE;
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704 case 0x13: {
05705 byte map_bits = 0;
05706 byte log_X = MapLogX() - 6;
05707 byte log_Y = MapLogY() - 6;
05708 byte max_edge = max(log_X, log_Y);
05709
05710 if (log_X == log_Y) {
05711 SetBit(map_bits, 0);
05712 } else {
05713 if (max_edge == log_Y) SetBit(map_bits, 1);
05714 }
05715
05716 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
05717 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
05718 }
05719
05720 default:
05721 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
05722 return 0;
05723 }
05724 }
05725
05726
05727 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
05728 {
05729 uint start = 0;
05730 uint size = 0;
05731
05732 if (op == 6) {
05733
05734 return grm[_cur_grffile->GetParam(target)];
05735 }
05736
05737
05738 if (op == 2 || op == 3) start = _cur_grffile->GetParam(target);
05739
05740 for (uint i = start; i < num_ids; i++) {
05741 if (grm[i] == 0) {
05742 size++;
05743 } else {
05744 if (op == 2 || op == 3) break;
05745 start = i + 1;
05746 size = 0;
05747 }
05748
05749 if (size == count) break;
05750 }
05751
05752 if (size == count) {
05753
05754 if (op == 0 || op == 3) {
05755 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
05756 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
05757 }
05758 return start;
05759 }
05760
05761
05762 if (op != 4 && op != 5) {
05763
05764 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
05765 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05766 return UINT_MAX;
05767 }
05768
05769 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
05770 return UINT_MAX;
05771 }
05772
05773
05774
05775 static void ParamSet(ByteReader *buf)
05776 {
05777
05778
05779
05780
05781
05782
05783
05784
05785
05786
05787
05788
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799 uint8 target = buf->ReadByte();
05800 uint8 oper = buf->ReadByte();
05801 uint32 src1 = buf->ReadByte();
05802 uint32 src2 = buf->ReadByte();
05803
05804 uint32 data = 0;
05805 if (buf->Remaining() >= 4) data = buf->ReadDWord();
05806
05807
05808
05809
05810
05811
05812
05813 if (HasBit(oper, 7)) {
05814 if (target < 0x80 && target < _cur_grffile->param_end) {
05815 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
05816 return;
05817 }
05818
05819 oper = GB(oper, 0, 7);
05820 }
05821
05822 if (src2 == 0xFE) {
05823 if (GB(data, 0, 8) == 0xFF) {
05824 if (data == 0x0000FFFF) {
05825
05826 src1 = GetPatchVariable(src1);
05827 } else {
05828
05829 uint8 op = src1;
05830 uint8 feature = GB(data, 8, 8);
05831 uint16 count = GB(data, 16, 16);
05832
05833 if (_cur_stage == GLS_RESERVE) {
05834 if (feature == 0x08) {
05835
05836 if (op == 0) {
05837
05838 if (_cur_spriteid + count >= 16384) {
05839 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
05840 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
05841 return;
05842 }
05843
05844
05845 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
05846 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
05847 _cur_spriteid += count;
05848 }
05849 }
05850
05851 src1 = 0;
05852 } else if (_cur_stage == GLS_ACTIVATION) {
05853 switch (feature) {
05854 case 0x00:
05855 case 0x01:
05856 case 0x02:
05857 case 0x03:
05858 if (!_settings_game.vehicle.dynamic_engines) {
05859 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
05860 if (_skip_sprites == -1) return;
05861 } else {
05862
05863 switch (op) {
05864 case 2:
05865 case 3:
05866 src1 = _cur_grffile->GetParam(target);
05867 break;
05868
05869 default:
05870 src1 = 0;
05871 break;
05872 }
05873 }
05874 break;
05875
05876 case 0x08:
05877 switch (op) {
05878 case 0:
05879
05880 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
05881 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
05882 break;
05883
05884 case 1:
05885 src1 = _cur_spriteid;
05886 break;
05887
05888 default:
05889 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
05890 return;
05891 }
05892 break;
05893
05894 case 0x0B:
05895
05896 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
05897 if (_skip_sprites == -1) return;
05898 break;
05899
05900 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
05901 }
05902 } else {
05903
05904 src1 = 0;
05905 }
05906 }
05907 } else {
05908
05909 const GRFFile *file = GetFileByGRFID(data);
05910 GRFConfig *c = GetGRFConfig(data);
05911 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
05912
05913 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
05914 src1 = 0;
05915 } else if (file == NULL || (c != NULL && c->status == GCS_DISABLED)) {
05916 src1 = 0;
05917 } else if (src1 == 0xFE) {
05918 src1 = c->version;
05919 } else {
05920 src1 = file->GetParam(src1);
05921 }
05922 }
05923 } else {
05924
05925
05926
05927
05928
05929 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
05930 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
05931 }
05932
05933
05934
05935
05936
05937
05938
05939 uint32 res;
05940 switch (oper) {
05941 case 0x00:
05942 res = src1;
05943 break;
05944
05945 case 0x01:
05946 res = src1 + src2;
05947 break;
05948
05949 case 0x02:
05950 res = src1 - src2;
05951 break;
05952
05953 case 0x03:
05954 res = src1 * src2;
05955 break;
05956
05957 case 0x04:
05958 res = (int32)src1 * (int32)src2;
05959 break;
05960
05961 case 0x05:
05962 if ((int32)src2 < 0) {
05963 res = src1 >> -(int32)src2;
05964 } else {
05965 res = src1 << src2;
05966 }
05967 break;
05968
05969 case 0x06:
05970 if ((int32)src2 < 0) {
05971 res = (int32)src1 >> -(int32)src2;
05972 } else {
05973 res = (int32)src1 << src2;
05974 }
05975 break;
05976
05977 case 0x07:
05978 res = src1 & src2;
05979 break;
05980
05981 case 0x08:
05982 res = src1 | src2;
05983 break;
05984
05985 case 0x09:
05986 if (src2 == 0) {
05987 res = src1;
05988 } else {
05989 res = src1 / src2;
05990 }
05991 break;
05992
05993 case 0x0A:
05994 if (src2 == 0) {
05995 res = src1;
05996 } else {
05997 res = (int32)src1 / (int32)src2;
05998 }
05999 break;
06000
06001 case 0x0B:
06002 if (src2 == 0) {
06003 res = src1;
06004 } else {
06005 res = src1 % src2;
06006 }
06007 break;
06008
06009 case 0x0C:
06010 if (src2 == 0) {
06011 res = src1;
06012 } else {
06013 res = (int32)src1 % (int32)src2;
06014 }
06015 break;
06016
06017 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
06018 }
06019
06020 switch (target) {
06021 case 0x8E:
06022 _cur_grffile->traininfo_vehicle_pitch = res;
06023 break;
06024
06025 case 0x8F: {
06026 extern RailtypeInfo _railtypes[RAILTYPE_END];
06027 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
06028 if (_settings_game.vehicle.disable_elrails) {
06029 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
06030 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
06031 } else {
06032 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
06033 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
06034 }
06035 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
06036 break;
06037 }
06038
06039
06040 case 0x93:
06041 case 0x94:
06042 case 0x95:
06043 case 0x96:
06044 case 0x97:
06045 case 0x99:
06046 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06047 break;
06048
06049 case 0x9E:
06050 _misc_grf_features = res;
06051
06052
06053 _cur_grffile->traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
06054
06055
06056 ClrBit(_misc_grf_features, GMB_TRAIN_WIDTH_32_PIXELS);
06057 break;
06058
06059 case 0x9F:
06060 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
06061 break;
06062
06063 default:
06064 if (target < 0x80) {
06065 _cur_grffile->param[target] = res;
06066
06067 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
06068 } else {
06069 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
06070 }
06071 break;
06072 }
06073 }
06074
06075
06076 static void SafeGRFInhibit(ByteReader *buf)
06077 {
06078
06079
06080
06081
06082
06083 uint8 num = buf->ReadByte();
06084
06085 for (uint i = 0; i < num; i++) {
06086 uint32 grfid = buf->ReadDWord();
06087
06088
06089 if (grfid != _cur_grfconfig->ident.grfid) {
06090 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06091
06092
06093 _skip_sprites = -1;
06094
06095 return;
06096 }
06097 }
06098 }
06099
06100
06101 static void GRFInhibit(ByteReader *buf)
06102 {
06103
06104
06105
06106
06107
06108 uint8 num = buf->ReadByte();
06109
06110 for (uint i = 0; i < num; i++) {
06111 uint32 grfid = buf->ReadDWord();
06112 GRFConfig *file = GetGRFConfig(grfid);
06113
06114
06115 if (file != NULL && file != _cur_grfconfig) {
06116 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
06117 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
06118 error->data = strdup(_cur_grfconfig->GetName());
06119 }
06120 }
06121 }
06122
06123
06124 static void FeatureTownName(ByteReader *buf)
06125 {
06126
06127
06128
06129
06130
06131
06132
06133 uint32 grfid = _cur_grffile->grfid;
06134
06135 GRFTownName *townname = AddGRFTownName(grfid);
06136
06137 byte id = buf->ReadByte();
06138 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
06139
06140 if (HasBit(id, 7)) {
06141
06142 ClrBit(id, 7);
06143 bool new_scheme = _cur_grffile->grf_version >= 7;
06144
06145 byte lang = buf->ReadByte();
06146
06147 byte nb_gen = townname->nb_gen;
06148 do {
06149 ClrBit(lang, 7);
06150
06151 const char *name = buf->ReadString();
06152
06153 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
06154 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
06155 free(lang_name);
06156
06157 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
06158
06159 lang = buf->ReadByte();
06160 } while (lang != 0);
06161 townname->id[nb_gen] = id;
06162 townname->nb_gen++;
06163 }
06164
06165 byte nb = buf->ReadByte();
06166 grfmsg(6, "FeatureTownName: %u parts", nb);
06167
06168 townname->nbparts[id] = nb;
06169 townname->partlist[id] = CallocT<NamePartList>(nb);
06170
06171 for (int i = 0; i < nb; i++) {
06172 byte nbtext = buf->ReadByte();
06173 townname->partlist[id][i].bitstart = buf->ReadByte();
06174 townname->partlist[id][i].bitcount = buf->ReadByte();
06175 townname->partlist[id][i].maxprob = 0;
06176 townname->partlist[id][i].partcount = nbtext;
06177 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
06178 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);
06179
06180 for (int j = 0; j < nbtext; j++) {
06181 byte prob = buf->ReadByte();
06182
06183 if (HasBit(prob, 7)) {
06184 byte ref_id = buf->ReadByte();
06185
06186 if (townname->nbparts[ref_id] == 0) {
06187 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
06188 DelGRFTownName(grfid);
06189 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
06190 return;
06191 }
06192
06193 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
06194 townname->partlist[id][i].parts[j].data.id = ref_id;
06195 } else {
06196 const char *text = buf->ReadString();
06197 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
06198 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
06199 }
06200 townname->partlist[id][i].parts[j].prob = prob;
06201 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
06202 }
06203 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
06204 }
06205 }
06206
06207
06208 static void DefineGotoLabel(ByteReader *buf)
06209 {
06210
06211
06212
06213
06214
06215 byte nfo_label = buf->ReadByte();
06216
06217 GRFLabel *label = MallocT<GRFLabel>(1);
06218 label->label = nfo_label;
06219 label->nfo_line = _nfo_line;
06220 label->pos = FioGetPos();
06221 label->next = NULL;
06222
06223
06224 if (_cur_grffile->label == NULL) {
06225 _cur_grffile->label = label;
06226 } else {
06227
06228 GRFLabel *l;
06229 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
06230 l->next = label;
06231 }
06232
06233 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
06234 }
06235
06236
06237 static void GRFSound(ByteReader *buf)
06238 {
06239
06240
06241
06242
06243 uint16 num = buf->ReadWord();
06244
06245 _grf_data_blocks = num;
06246 _grf_data_type = GDT_SOUND;
06247
06248 if (_cur_grffile->sound_offset == 0) {
06249 _cur_grffile->sound_offset = GetNumSounds();
06250 _cur_grffile->num_sounds = num;
06251 }
06252 }
06253
06254
06255 static void SkipAct11(ByteReader *buf)
06256 {
06257
06258
06259
06260
06261 _skip_sprites = buf->ReadWord();
06262
06263 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
06264 }
06265
06266 static void ImportGRFSound(ByteReader *buf)
06267 {
06268 const GRFFile *file;
06269 SoundEntry *sound = AllocateSound();
06270 uint32 grfid = buf->ReadDWord();
06271 SoundID sound_id = buf->ReadWord();
06272
06273 file = GetFileByGRFID(grfid);
06274 if (file == NULL || file->sound_offset == 0) {
06275 grfmsg(1, "ImportGRFSound: Source file not available");
06276 return;
06277 }
06278
06279 if (sound_id >= file->num_sounds) {
06280 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
06281 return;
06282 }
06283
06284 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
06285
06286 *sound = *GetSound(file->sound_offset + sound_id);
06287
06288
06289 sound->volume = 128;
06290 sound->priority = 0;
06291 }
06292
06293
06294 static void GRFImportBlock(ByteReader *buf)
06295 {
06296 if (_grf_data_blocks == 0) {
06297 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
06298 return;
06299 }
06300
06301 _grf_data_blocks--;
06302
06303
06304
06305 if (buf->ReadByte() != _grf_data_type) {
06306 grfmsg(1, "GRFImportBlock: Import type mismatch");
06307 }
06308
06309 switch (_grf_data_type) {
06310 case GDT_SOUND: ImportGRFSound(buf); break;
06311 default: NOT_REACHED();
06312 }
06313 }
06314
06315 static void LoadGRFSound(ByteReader *buf)
06316 {
06317
06318
06319 SoundEntry *sound = AllocateSound();
06320
06321 if (buf->ReadDWord() != BSWAP32('RIFF')) {
06322 grfmsg(1, "LoadGRFSound: Missing RIFF header");
06323 return;
06324 }
06325
06326 uint32 total_size = buf->ReadDWord();
06327 if (total_size > buf->Remaining()) {
06328 grfmsg(1, "LoadGRFSound: RIFF was truncated");
06329 return;
06330 }
06331
06332 if (buf->ReadDWord() != BSWAP32('WAVE')) {
06333 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
06334 return;
06335 }
06336
06337 while (total_size >= 8) {
06338 uint32 tag = buf->ReadDWord();
06339 uint32 size = buf->ReadDWord();
06340 total_size -= 8;
06341 if (total_size < size) {
06342 grfmsg(1, "LoadGRFSound: Invalid RIFF");
06343 return;
06344 }
06345 total_size -= size;
06346
06347 switch (tag) {
06348 case ' tmf':
06349
06350 if (size < 16 || buf->ReadWord() != 1) {
06351 grfmsg(1, "LoadGRFSound: Invalid audio format");
06352 return;
06353 }
06354 sound->channels = buf->ReadWord();
06355 sound->rate = buf->ReadDWord();
06356 buf->ReadDWord();
06357 buf->ReadWord();
06358 sound->bits_per_sample = buf->ReadWord();
06359
06360
06361 size -= 16;
06362 break;
06363
06364 case 'atad':
06365 sound->file_size = size;
06366 sound->file_offset = FioGetPos() - buf->Remaining();
06367 sound->file_slot = _file_index;
06368
06369
06370 sound->volume = 0x80;
06371 sound->priority = 0;
06372
06373 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", sound->channels, sound->rate, sound->bits_per_sample, size);
06374 return;
06375
06376 default:
06377
06378 break;
06379 }
06380
06381
06382 for (; size > 0; size--) buf->ReadByte();
06383 }
06384
06385 grfmsg(1, "LoadGRFSound: RIFF does not contain any sound data");
06386
06387
06388 MemSetT(sound, 0);
06389 }
06390
06391
06392 static void LoadFontGlyph(ByteReader *buf)
06393 {
06394
06395
06396
06397
06398
06399
06400
06401 uint8 num_def = buf->ReadByte();
06402
06403 for (uint i = 0; i < num_def; i++) {
06404 FontSize size = (FontSize)buf->ReadByte();
06405 uint8 num_char = buf->ReadByte();
06406 uint16 base_char = buf->ReadWord();
06407
06408 if (size >= FS_END) {
06409 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
06410 }
06411
06412 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
06413
06414 for (uint c = 0; c < num_char; c++) {
06415 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
06416 _nfo_line++;
06417 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
06418 }
06419 }
06420 }
06421
06422
06423 static void SkipAct12(ByteReader *buf)
06424 {
06425
06426
06427
06428
06429
06430
06431
06432 uint8 num_def = buf->ReadByte();
06433
06434 for (uint i = 0; i < num_def; i++) {
06435
06436 buf->ReadByte();
06437
06438
06439 _skip_sprites += buf->ReadByte();
06440
06441
06442 buf->ReadWord();
06443 }
06444
06445 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
06446 }
06447
06448
06449 static void TranslateGRFStrings(ByteReader *buf)
06450 {
06451
06452
06453
06454
06455
06456
06457
06458 uint32 grfid = buf->ReadDWord();
06459 const GRFConfig *c = GetGRFConfig(grfid);
06460 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
06461 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
06462 return;
06463 }
06464
06465 if (c->status == GCS_INITIALISED) {
06466
06467
06468 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
06469
06470 char tmp[256];
06471 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
06472 error->data = strdup(tmp);
06473
06474 return;
06475 }
06476
06477 byte num_strings = buf->ReadByte();
06478 uint16 first_id = buf->ReadWord();
06479
06480 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
06481 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
06482 return;
06483 }
06484
06485 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
06486 const char *string = buf->ReadString();
06487
06488 if (StrEmpty(string)) {
06489 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
06490 continue;
06491 }
06492
06493
06494
06495
06496
06497
06498 AddGRFString(grfid, first_id + i, 0x7F, true, true, string, STR_UNDEFINED);
06499 }
06500 }
06501
06503 static bool ChangeGRFName(byte langid, const char *str)
06504 {
06505 AddGRFTextToList(&_cur_grfconfig->name->text, langid, _cur_grfconfig->ident.grfid, false, str);
06506 return true;
06507 }
06508
06510 static bool ChangeGRFDescription(byte langid, const char *str)
06511 {
06512 AddGRFTextToList(&_cur_grfconfig->info->text, langid, _cur_grfconfig->ident.grfid, true, str);
06513 return true;
06514 }
06515
06517 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
06518 {
06519 if (len != 1) {
06520 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
06521 buf->Skip(len);
06522 } else {
06523 _cur_grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur_grfconfig->param));
06524 }
06525 return true;
06526 }
06527
06529 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
06530 {
06531 if (len != 1) {
06532 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
06533 buf->Skip(len);
06534 } else {
06535 char data = buf->ReadByte();
06536 GRFPalette pal = GRFP_GRF_UNSET;
06537 switch (data) {
06538 case '*':
06539 case 'A': pal = GRFP_GRF_ANY; break;
06540 case 'W': pal = GRFP_GRF_WINDOWS; break;
06541 case 'D': pal = GRFP_GRF_DOS; break;
06542 default:
06543 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
06544 break;
06545 }
06546 if (pal != GRFP_GRF_UNSET) {
06547 _cur_grfconfig->palette &= ~GRFP_GRF_MASK;
06548 _cur_grfconfig->palette |= pal;
06549 }
06550 }
06551 return true;
06552 }
06553
06555 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
06556 {
06557 if (len != 4) {
06558 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
06559 buf->Skip(len);
06560 } else {
06561
06562 _cur_grfconfig->version = _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06563 }
06564 return true;
06565 }
06566
06568 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
06569 {
06570 if (len != 4) {
06571 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
06572 buf->Skip(len);
06573 } else {
06574 _cur_grfconfig->min_loadable_version = buf->ReadDWord();
06575 if (_cur_grfconfig->version == 0) {
06576 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
06577 _cur_grfconfig->min_loadable_version = 0;
06578 }
06579 if (_cur_grfconfig->version < _cur_grfconfig->min_loadable_version) {
06580 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur_grfconfig->min_loadable_version);
06581 _cur_grfconfig->min_loadable_version = _cur_grfconfig->version;
06582 }
06583 }
06584 return true;
06585 }
06586
06587 static GRFParameterInfo *_cur_parameter;
06588
06590 static bool ChangeGRFParamName(byte langid, const char *str)
06591 {
06592 AddGRFTextToList(&_cur_parameter->name, langid, _cur_grfconfig->ident.grfid, false, str);
06593 return true;
06594 }
06595
06597 static bool ChangeGRFParamDescription(byte langid, const char *str)
06598 {
06599 AddGRFTextToList(&_cur_parameter->desc, langid, _cur_grfconfig->ident.grfid, true, str);
06600 return true;
06601 }
06602
06604 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
06605 {
06606 if (len != 1) {
06607 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
06608 buf->Skip(len);
06609 } else {
06610 GRFParameterType type = (GRFParameterType)buf->ReadByte();
06611 if (type < PTYPE_END) {
06612 _cur_parameter->type = type;
06613 } else {
06614 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
06615 }
06616 }
06617 return true;
06618 }
06619
06621 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
06622 {
06623 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
06624 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
06625 buf->Skip(len);
06626 } else if (len != 8) {
06627 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
06628 buf->Skip(len);
06629 } else {
06630 _cur_parameter->min_value = buf->ReadDWord();
06631 _cur_parameter->max_value = buf->ReadDWord();
06632 }
06633 return true;
06634 }
06635
06637 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
06638 {
06639 if (len < 1 || len > 3) {
06640 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
06641 buf->Skip(len);
06642 } else {
06643 byte param_nr = buf->ReadByte();
06644 if (param_nr >= lengthof(_cur_grfconfig->param)) {
06645 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
06646 buf->Skip(len - 1);
06647 } else {
06648 _cur_parameter->param_nr = param_nr;
06649 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
06650 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
06651 }
06652 }
06653
06654 return true;
06655 }
06656
06658 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
06659 {
06660 if (len != 4) {
06661 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
06662 buf->Skip(len);
06663 } else {
06664 _cur_parameter->def_value = buf->ReadDWord();
06665 }
06666 _cur_grfconfig->has_param_defaults = true;
06667 return true;
06668 }
06669
06670 typedef bool (*DataHandler)(size_t, ByteReader *);
06671 typedef bool (*TextHandler)(byte, const char *str);
06672 typedef bool (*BranchHandler)(ByteReader *);
06673
06681 struct AllowedSubtags {
06683 AllowedSubtags() :
06684 id(0),
06685 type(0)
06686 {}
06687
06693 AllowedSubtags(uint32 id, DataHandler handler) :
06694 id(id),
06695 type('B')
06696 {
06697 this->handler.data = handler;
06698 }
06699
06705 AllowedSubtags(uint32 id, TextHandler handler) :
06706 id(id),
06707 type('T')
06708 {
06709 this->handler.text = handler;
06710 }
06711
06717 AllowedSubtags(uint32 id, BranchHandler handler) :
06718 id(id),
06719 type('C')
06720 {
06721 this->handler.call_handler = true;
06722 this->handler.u.branch = handler;
06723 }
06724
06730 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
06731 id(id),
06732 type('C')
06733 {
06734 this->handler.call_handler = false;
06735 this->handler.u.subtags = subtags;
06736 }
06737
06738 uint32 id;
06739 byte type;
06740 union {
06741 DataHandler data;
06742 TextHandler text;
06743 struct {
06744 union {
06745 BranchHandler branch;
06746 AllowedSubtags *subtags;
06747 } u;
06748 bool call_handler;
06749 };
06750 } handler;
06751 };
06752
06753 static bool SkipUnknownInfo(ByteReader *buf, byte type);
06754 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
06755
06762 static bool ChangeGRFParamValueNames(ByteReader *buf)
06763 {
06764 byte type = buf->ReadByte();
06765 while (type != 0) {
06766 uint32 id = buf->ReadDWord();
06767 if (type != 'T' || id > _cur_parameter->max_value) {
06768 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
06769 if (!SkipUnknownInfo(buf, type)) return false;
06770 type = buf->ReadByte();
06771 continue;
06772 }
06773
06774 byte langid = buf->ReadByte();
06775 const char *name_string = buf->ReadString();
06776
06777 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
06778 if (val_name != _cur_parameter->value_names.End()) {
06779 AddGRFTextToList(&val_name->second, langid, _cur_grfconfig->ident.grfid, false, name_string);
06780 } else {
06781 GRFText *list = NULL;
06782 AddGRFTextToList(&list, langid, _cur_grfconfig->ident.grfid, false, name_string);
06783 _cur_parameter->value_names.Insert(id, list);
06784 }
06785
06786 type = buf->ReadByte();
06787 }
06788 return true;
06789 }
06790
06791 AllowedSubtags _tags_parameters[] = {
06792 AllowedSubtags('NAME', ChangeGRFParamName),
06793 AllowedSubtags('DESC', ChangeGRFParamDescription),
06794 AllowedSubtags('TYPE', ChangeGRFParamType),
06795 AllowedSubtags('LIMI', ChangeGRFParamLimits),
06796 AllowedSubtags('MASK', ChangeGRFParamMask),
06797 AllowedSubtags('VALU', ChangeGRFParamValueNames),
06798 AllowedSubtags('DFLT', ChangeGRFParamDefault),
06799 AllowedSubtags()
06800 };
06801
06808 static bool HandleParameterInfo(ByteReader *buf)
06809 {
06810 byte type = buf->ReadByte();
06811 while (type != 0) {
06812 uint32 id = buf->ReadDWord();
06813 if (type != 'C' || id >= _cur_grfconfig->num_valid_params) {
06814 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
06815 if (!SkipUnknownInfo(buf, type)) return false;
06816 type = buf->ReadByte();
06817 continue;
06818 }
06819
06820 if (id >= _cur_grfconfig->param_info.Length()) {
06821 uint num_to_add = id - _cur_grfconfig->param_info.Length() + 1;
06822 GRFParameterInfo **newdata = _cur_grfconfig->param_info.Append(num_to_add);
06823 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
06824 }
06825 if (_cur_grfconfig->param_info[id] == NULL) {
06826 _cur_grfconfig->param_info[id] = new GRFParameterInfo(id);
06827 }
06828 _cur_parameter = _cur_grfconfig->param_info[id];
06829
06830 if (!HandleNodes(buf, _tags_parameters)) return false;
06831 type = buf->ReadByte();
06832 }
06833 return true;
06834 }
06835
06836 AllowedSubtags _tags_info[] = {
06837 AllowedSubtags('NAME', ChangeGRFName),
06838 AllowedSubtags('DESC', ChangeGRFDescription),
06839 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
06840 AllowedSubtags('PALS', ChangeGRFPalette),
06841 AllowedSubtags('VRSN', ChangeGRFVersion),
06842 AllowedSubtags('MINV', ChangeGRFMinVersion),
06843 AllowedSubtags('PARA', HandleParameterInfo),
06844 AllowedSubtags()
06845 };
06846
06847 AllowedSubtags _tags_root[] = {
06848 AllowedSubtags('INFO', _tags_info),
06849 AllowedSubtags()
06850 };
06851
06852
06857 static bool SkipUnknownInfo(ByteReader *buf, byte type)
06858 {
06859
06860 switch (type) {
06861 case 'C': {
06862 byte new_type = buf->ReadByte();
06863 while (new_type != 0) {
06864 buf->ReadDWord();
06865 if (!SkipUnknownInfo(buf, new_type)) return false;
06866 new_type = buf->ReadByte();
06867 }
06868 break;
06869 }
06870
06871 case 'T':
06872 buf->ReadByte();
06873 buf->ReadString();
06874 break;
06875
06876 case 'B': {
06877 uint16 size = buf->ReadWord();
06878 buf->Skip(size);
06879 break;
06880 }
06881
06882 default:
06883 return false;
06884 }
06885
06886 return true;
06887 }
06888
06889 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
06890 {
06891 uint i = 0;
06892 AllowedSubtags *tag;
06893 while ((tag = &subtags[i++])->type != 0) {
06894 if (tag->id != BSWAP32(id) || tag->type != type) continue;
06895 switch (type) {
06896 default: NOT_REACHED();
06897
06898 case 'T': {
06899 byte langid = buf->ReadByte();
06900 return tag->handler.text(langid, buf->ReadString());
06901 }
06902
06903 case 'B': {
06904 size_t len = buf->ReadWord();
06905 if (buf->Remaining() < len) return false;
06906 return tag->handler.data(len, buf);
06907 }
06908
06909 case 'C': {
06910 if (tag->handler.call_handler) {
06911 return tag->handler.u.branch(buf);
06912 }
06913 return HandleNodes(buf, tag->handler.u.subtags);
06914 }
06915 }
06916 }
06917 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
06918 return SkipUnknownInfo(buf, type);
06919 }
06920
06921 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
06922 {
06923 byte type = buf->ReadByte();
06924 while (type != 0) {
06925 uint32 id = buf->ReadDWord();
06926 if (!HandleNode(type, id, buf, subtags)) return false;
06927 type = buf->ReadByte();
06928 }
06929 return true;
06930 }
06931
06932
06933 static void StaticGRFInfo(ByteReader *buf)
06934 {
06935
06936 HandleNodes(buf, _tags_root);
06937 }
06938
06939
06940 static void GRFDataBlock(ByteReader *buf)
06941 {
06942
06943
06944 if (_grf_data_blocks == 0) {
06945 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
06946 return;
06947 }
06948
06949 uint8 name_len = buf->ReadByte();
06950 const char *name = reinterpret_cast<const char *>(buf->Data());
06951 buf->Skip(name_len);
06952
06953
06954 if (buf->ReadByte() != 0) {
06955 grfmsg(2, "GRFDataBlock: Name not properly terminated");
06956 return;
06957 }
06958
06959 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
06960
06961 _grf_data_blocks--;
06962
06963 switch (_grf_data_type) {
06964 case GDT_SOUND: LoadGRFSound(buf); break;
06965 default: NOT_REACHED();
06966 }
06967 }
06968
06969
06970
06971 static void GRFUnsafe(ByteReader *buf)
06972 {
06973 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
06974
06975
06976 _skip_sprites = -1;
06977 }
06978
06979
06980 static void InitializeGRFSpecial()
06981 {
06982 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C)
06983 | (1 << 0x0D)
06984 | (1 << 0x0E)
06985 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F)
06986 | (0 << 0x10)
06987 | (1 << 0x12)
06988 | (1 << 0x13)
06989 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
06990 | (1 << 0x1B)
06991 | (1 << 0x1D)
06992 | (1 << 0x1E);
06993
06994 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
06995 | (1 << 0x08)
06996 | (1 << 0x09)
06997 | (0 << 0x0B)
06998 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
06999 | (1 << 0x12)
07000 | (1 << 0x13)
07001 | (1 << 0x14)
07002 | (1 << 0x16)
07003 | (1 << 0x17)
07004 | (1 << 0x18)
07005 | (1 << 0x19)
07006 | (1 << 0x1A)
07007 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
07008 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
07009
07010 _ttdpatch_flags[2] = (1 << 0x01)
07011 | (1 << 0x03)
07012 | (1 << 0x0A)
07013 | (0 << 0x0B)
07014 | (0 << 0x0C)
07015 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
07016 | (1 << 0x0E)
07017 | (1 << 0x0F)
07018 | (0 << 0x10)
07019 | (0 << 0x11)
07020 | (1 << 0x12)
07021 | (1 << 0x13)
07022 | (1 << 0x14)
07023 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
07024 | (1 << 0x16)
07025 | (1 << 0x17)
07026 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
07027 | (1 << 0x19)
07028 | (1 << 0x1A)
07029 | (1 << 0x1B)
07030 | (1 << 0x1C)
07031 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
07032 | (1 << 0x1E)
07033 | (0 << 0x1F);
07034
07035 _ttdpatch_flags[3] = (0 << 0x00)
07036 | (1 << 0x01)
07037 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
07038 | (1 << 0x03)
07039 | (0 << 0x04)
07040 | (1 << 0x05)
07041 | (1 << 0x06)
07042 | (1 << 0x07)
07043 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
07044 | (0 << 0x09)
07045 | (0 << 0x0A)
07046 | (1 << 0x0B)
07047 | (1 << 0x0C)
07048 | (1 << 0x0D)
07049 | (1 << 0x0E)
07050 | (1 << 0x0F)
07051 | (1 << 0x10)
07052 | (1 << 0x11)
07053 | (1 << 0x12)
07054 | (0 << 0x13)
07055 | (1 << 0x14)
07056 | (0 << 0x15)
07057 | (1 << 0x16)
07058 | (1 << 0x17)
07059 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
07060 | (1 << 0x1E)
07061 | (1 << 0x1F);
07062 }
07063
07064 static void ResetCustomStations()
07065 {
07066 const GRFFile * const *end = _grf_files.End();
07067 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07068 StationSpec **&stations = (*file)->stations;
07069 if (stations == NULL) continue;
07070 for (uint i = 0; i < MAX_STATIONS; i++) {
07071 if (stations[i] == NULL) continue;
07072 StationSpec *statspec = stations[i];
07073
07074 for (uint t = 0; t < statspec->tiles; t++) {
07075 free((void*)statspec->renderdata[t].seq);
07076 }
07077 free(statspec->renderdata);
07078
07079
07080 if (!statspec->copied_layouts) {
07081 for (uint l = 0; l < statspec->lengths; l++) {
07082 for (uint p = 0; p < statspec->platforms[l]; p++) {
07083 free(statspec->layouts[l][p]);
07084 }
07085 free(statspec->layouts[l]);
07086 }
07087 free(statspec->layouts);
07088 free(statspec->platforms);
07089 }
07090
07091
07092 free(statspec);
07093 }
07094
07095
07096 free(stations);
07097 stations = NULL;
07098 }
07099 }
07100
07101 static void ResetCustomHouses()
07102 {
07103 const GRFFile * const *end = _grf_files.End();
07104 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07105 HouseSpec **&housespec = (*file)->housespec;
07106 if (housespec == NULL) continue;
07107 for (uint i = 0; i < HOUSE_MAX; i++) {
07108 free(housespec[i]);
07109 }
07110
07111 free(housespec);
07112 housespec = NULL;
07113 }
07114 }
07115
07116 static void ResetCustomAirports()
07117 {
07118 const GRFFile * const *end = _grf_files.End();
07119 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07120 AirportSpec **aslist = (*file)->airportspec;
07121 if (aslist != NULL) {
07122 for (uint i = 0; i < NUM_AIRPORTS; i++) {
07123 AirportSpec *as = aslist[i];
07124
07125 if (as != NULL) {
07126
07127 for (int j = 0; j < as->num_table; j++) {
07128
07129 free((void*)as->table[j]);
07130 }
07131 free((void*)as->table);
07132 free((void*)as->depot_table);
07133
07134 free(as);
07135 }
07136 }
07137 free(aslist);
07138 (*file)->airportspec = NULL;
07139 }
07140
07141 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07142 if (airporttilespec != NULL) {
07143 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07144 free(airporttilespec[i]);
07145 }
07146 free(airporttilespec);
07147 airporttilespec = NULL;
07148 }
07149 }
07150 }
07151
07152 static void ResetCustomIndustries()
07153 {
07154 const GRFFile * const *end = _grf_files.End();
07155 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07156 IndustrySpec **&industryspec = (*file)->industryspec;
07157 IndustryTileSpec **&indtspec = (*file)->indtspec;
07158
07159
07160
07161 if (industryspec != NULL) {
07162 for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) {
07163 IndustrySpec *ind = industryspec[i];
07164 if (ind == NULL) continue;
07165
07166
07167 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
07168 free((void*)ind->random_sounds);
07169 }
07170
07171
07172 CleanIndustryTileTable(ind);
07173
07174 free(ind);
07175 }
07176
07177 free(industryspec);
07178 industryspec = NULL;
07179 }
07180
07181 if (indtspec == NULL) continue;
07182 for (uint i = 0; i < NUM_INDUSTRYTILES; i++) {
07183 free(indtspec[i]);
07184 }
07185
07186 free(indtspec);
07187 indtspec = NULL;
07188 }
07189 }
07190
07191 static void ResetCustomObjects()
07192 {
07193 const GRFFile * const *end = _grf_files.End();
07194 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07195 ObjectSpec **&objectspec = (*file)->objectspec;
07196 if (objectspec == NULL) continue;
07197 for (uint i = 0; i < NUM_OBJECTS; i++) {
07198 free(objectspec[i]);
07199 }
07200
07201 free(objectspec);
07202 objectspec = NULL;
07203 }
07204 }
07205
07206
07207 static void ResetNewGRF()
07208 {
07209 const GRFFile * const *end = _grf_files.End();
07210 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07211 GRFFile *f = *file;
07212 free(f->filename);
07213 free(f->cargo_list);
07214 free(f->railtype_list);
07215 delete [] f->language_map;
07216 free(f);
07217 }
07218
07219 _grf_files.Clear();
07220 _cur_grffile = NULL;
07221 }
07222
07223 static void ResetNewGRFErrors()
07224 {
07225 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
07226 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
07227 delete c->error;
07228 c->error = NULL;
07229 }
07230 }
07231 }
07232
07237 void ResetNewGRFData()
07238 {
07239 CleanUpStrings();
07240 CleanUpGRFTownNames();
07241
07242
07243 SetupEngines();
07244
07245
07246 ResetBridges();
07247
07248
07249 ResetRailTypes();
07250
07251
07252 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
07253
07254
07255 Engine *e;
07256 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
07257 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
07258 }
07259
07260
07261 memset(&_grm_engines, 0, sizeof(_grm_engines));
07262 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
07263
07264
07265 ResetGenericCallbacks();
07266
07267
07268 ResetPriceBaseMultipliers();
07269
07270
07271 ResetCurrencies();
07272
07273
07274 ResetCustomHouses();
07275 ResetHouses();
07276
07277
07278 ResetCustomIndustries();
07279 ResetIndustries();
07280
07281
07282 ObjectClass::Reset();
07283 ResetCustomObjects();
07284 ResetObjects();
07285
07286
07287 StationClass::Reset();
07288 ResetCustomStations();
07289
07290
07291 AirportClass::Reset();
07292 ResetCustomAirports();
07293 AirportSpec::ResetAirports();
07294 AirportTileSpec::ResetAirportTiles();
07295
07296
07297 memset(_water_feature, 0, sizeof(_water_feature));
07298
07299
07300 ClearSnowLine();
07301
07302
07303 ResetNewGRF();
07304
07305
07306 ResetNewGRFErrors();
07307
07308
07309 SetupCargoForClimate(_settings_game.game_creation.landscape);
07310
07311
07312 _misc_grf_features = 0;
07313
07314 _loaded_newgrf_features.has_2CC = false;
07315 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
07316 _loaded_newgrf_features.has_newhouses = false;
07317 _loaded_newgrf_features.has_newindustries = false;
07318 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
07319
07320
07321 _grf_id_overrides.clear();
07322
07323 InitializeSoundPool();
07324 _spritegroup_pool.CleanPool();
07325 }
07326
07330 void ResetPersistentNewGRFData()
07331 {
07332
07333 _engine_mngr.ResetToDefaultMapping();
07334 _house_mngr.ResetMapping();
07335 _industry_mngr.ResetMapping();
07336 _industile_mngr.ResetMapping();
07337 _airport_mngr.ResetMapping();
07338 _airporttile_mngr.ResetMapping();
07339 }
07340
07341 static void BuildCargoTranslationMap()
07342 {
07343 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
07344
07345 for (CargoID c = 0; c < NUM_CARGO; c++) {
07346 const CargoSpec *cs = CargoSpec::Get(c);
07347 if (!cs->IsValid()) continue;
07348
07349 if (_cur_grffile->cargo_max == 0) {
07350
07351 _cur_grffile->cargo_map[c] = cs->bitnum;
07352 } else {
07353
07354 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
07355 if (cs->label == _cur_grffile->cargo_list[i]) {
07356 _cur_grffile->cargo_map[c] = i;
07357 break;
07358 }
07359 }
07360 }
07361 }
07362 }
07363
07364 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
07365 {
07366 GRFFile *newfile = GetFileByFilename(config->filename);
07367 if (newfile != NULL) {
07368
07369 newfile->sprite_offset = sprite_offset;
07370 _cur_grffile = newfile;
07371 return;
07372 }
07373
07374 newfile = CallocT<GRFFile>(1);
07375
07376 newfile->filename = strdup(config->filename);
07377 newfile->sprite_offset = sprite_offset;
07378 newfile->grfid = config->ident.grfid;
07379
07380
07381 newfile->traininfo_vehicle_pitch = 0;
07382 newfile->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
07383
07384
07385 for (Price i = PR_BEGIN; i < PR_END; i++) {
07386 newfile->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
07387 }
07388
07389
07390 memset(newfile->railtype_map, INVALID_RAILTYPE, sizeof newfile->railtype_map);
07391 newfile->railtype_map[0] = RAILTYPE_RAIL;
07392 newfile->railtype_map[1] = RAILTYPE_ELECTRIC;
07393 newfile->railtype_map[2] = RAILTYPE_MONO;
07394 newfile->railtype_map[3] = RAILTYPE_MAGLEV;
07395
07396
07397
07398 assert_compile(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
07399 memset(newfile->param, 0, sizeof(newfile->param));
07400
07401 assert(config->num_params <= lengthof(config->param));
07402 newfile->param_end = config->num_params;
07403 if (newfile->param_end > 0) {
07404 MemCpyT(newfile->param, config->param, newfile->param_end);
07405 }
07406
07407 *_grf_files.Append() = _cur_grffile = newfile;
07408 }
07409
07410
07415 static const CargoLabel _default_refitmasks_rail[] = {
07416 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
07417 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
07418 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07419 'PLST', 'FZDR',
07420 0 };
07421
07422 static const CargoLabel _default_refitmasks_road[] = {
07423 0 };
07424
07425 static const CargoLabel _default_refitmasks_ships[] = {
07426 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
07427 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
07428 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
07429 'PLST', 'FZDR',
07430 0 };
07431
07432 static const CargoLabel _default_refitmasks_aircraft[] = {
07433 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
07434 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
07435 0 };
07436
07437 static const CargoLabel * const _default_refitmasks[] = {
07438 _default_refitmasks_rail,
07439 _default_refitmasks_road,
07440 _default_refitmasks_ships,
07441 _default_refitmasks_aircraft,
07442 };
07443
07444
07448 static void CalculateRefitMasks()
07449 {
07450 Engine *e;
07451
07452 FOR_ALL_ENGINES(e) {
07453 EngineID engine = e->index;
07454 EngineInfo *ei = &e->info;
07455 uint32 mask = 0;
07456 uint32 not_mask = 0;
07457 uint32 xor_mask = 0;
07458
07459
07460 if (_gted[engine].refitmask_valid) {
07461 if (ei->refit_mask != 0) {
07462 const GRFFile *file = _gted[engine].refitmask_grf;
07463 if (file == NULL) file = e->grf_prop.grffile;
07464 if (file != NULL && file->cargo_max != 0) {
07465
07466 uint num_cargo = min(32, file->cargo_max);
07467 for (uint i = 0; i < num_cargo; i++) {
07468 if (!HasBit(ei->refit_mask, i)) continue;
07469
07470 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
07471 if (c == CT_INVALID) continue;
07472
07473 SetBit(xor_mask, c);
07474 }
07475 } else {
07476
07477 const CargoSpec *cs;
07478 FOR_ALL_CARGOSPECS(cs) {
07479 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
07480 }
07481 }
07482 }
07483
07484 if (_gted[engine].cargo_allowed != 0) {
07485
07486 const CargoSpec *cs;
07487 FOR_ALL_CARGOSPECS(cs) {
07488 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
07489 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
07490 }
07491 }
07492 } else {
07493
07494 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
07495 const CargoLabel *cl = _default_refitmasks[e->type];
07496 for (uint i = 0;; i++) {
07497 if (cl[i] == 0) break;
07498
07499 CargoID cargo = GetCargoIDByLabel(cl[i]);
07500 if (cargo == CT_INVALID) continue;
07501
07502 SetBit(xor_mask, cargo);
07503 }
07504 }
07505 }
07506
07507 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
07508
07509
07510
07511 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
07512 if (ei->cargo_type == CT_INVALID) ei->climates = 0x80;
07513
07514
07515 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) ei->refit_mask = 0;
07516 }
07517 }
07518
07520 static void FinaliseCanals()
07521 {
07522 for (uint i = 0; i < CF_END; i++) {
07523 if (_water_feature[i].grffile != NULL) {
07524 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
07525 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
07526 }
07527 }
07528 }
07529
07531 static void FinaliseEngineArray()
07532 {
07533 Engine *e;
07534
07535 FOR_ALL_ENGINES(e) {
07536 if (e->grf_prop.grffile == NULL) {
07537 const EngineIDMapping &eid = _engine_mngr[e->index];
07538 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
07539 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
07540 }
07541 }
07542
07543
07544
07545
07546 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->grf_prop.grffile != NULL && is_custom_sprite(e->u.rail.image_index)) {
07547 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
07548 }
07549
07550
07551 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
07552 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
07553 SetBit(_loaded_newgrf_features.used_liveries, ls);
07554
07555
07556 if (e->type == VEH_TRAIN) {
07557 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
07558 switch (ls) {
07559 case LS_STEAM:
07560 case LS_DIESEL:
07561 case LS_ELECTRIC:
07562 case LS_MONORAIL:
07563 case LS_MAGLEV:
07564 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
07565 break;
07566
07567 case LS_DMU:
07568 case LS_EMU:
07569 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
07570 break;
07571
07572 default: NOT_REACHED();
07573 }
07574 }
07575 }
07576 }
07577 }
07578
07580 static void FinaliseCargoArray()
07581 {
07582 for (CargoID c = 0; c < NUM_CARGO; c++) {
07583 CargoSpec *cs = CargoSpec::Get(c);
07584 if (!cs->IsValid()) {
07585 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
07586 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
07587 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
07588 }
07589 }
07590 }
07591
07603 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
07604 {
07605 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
07606 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
07607 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
07608 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
07609 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
07610 hs->enabled = false;
07611 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);
07612 return false;
07613 }
07614
07615
07616
07617
07618 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
07619 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
07620 hs->enabled = false;
07621 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);
07622 return false;
07623 }
07624
07625
07626
07627 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
07628 hs->enabled = false;
07629 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);
07630 return false;
07631 }
07632
07633
07634 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
07635 hs->enabled = false;
07636 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);
07637 return false;
07638 }
07639
07640 return true;
07641 }
07642
07649 static void EnsureEarlyHouse(HouseZones bitmask)
07650 {
07651 Year min_year = MAX_YEAR;
07652
07653 for (int i = 0; i < HOUSE_MAX; i++) {
07654 HouseSpec *hs = HouseSpec::Get(i);
07655 if (hs == NULL || !hs->enabled) continue;
07656 if ((hs->building_availability & bitmask) != bitmask) continue;
07657 if (hs->min_year < min_year) min_year = hs->min_year;
07658 }
07659
07660 if (min_year == 0) return;
07661
07662 for (int i = 0; i < HOUSE_MAX; i++) {
07663 HouseSpec *hs = HouseSpec::Get(i);
07664 if (hs == NULL || !hs->enabled) continue;
07665 if ((hs->building_availability & bitmask) != bitmask) continue;
07666 if (hs->min_year == min_year) hs->min_year = 0;
07667 }
07668 }
07669
07676 static void FinaliseHouseArray()
07677 {
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687 const GRFFile * const *end = _grf_files.End();
07688 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07689 HouseSpec **&housespec = (*file)->housespec;
07690 if (housespec == NULL) continue;
07691
07692 for (int i = 0; i < HOUSE_MAX; i++) {
07693 HouseSpec *hs = housespec[i];
07694
07695 if (hs == NULL) continue;
07696
07697 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? housespec[i + 1] : NULL);
07698 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? housespec[i + 2] : NULL);
07699 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? housespec[i + 3] : NULL);
07700
07701 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
07702
07703 _house_mngr.SetEntitySpec(hs);
07704 }
07705 }
07706
07707 for (int i = 0; i < HOUSE_MAX; i++) {
07708 HouseSpec *hs = HouseSpec::Get(i);
07709 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? HouseSpec::Get(i + 1) : NULL);
07710 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? HouseSpec::Get(i + 2) : NULL);
07711 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? HouseSpec::Get(i + 3) : NULL);
07712
07713
07714
07715 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
07716
07717
07718
07719
07720
07721
07722
07723 hs->building_flags = TILE_NO_FLAG;
07724 }
07725 }
07726
07727 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
07728 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
07729 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
07730 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
07731 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
07732 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
07733
07734 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
07735 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
07736 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
07737 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
07738 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
07739 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
07740 }
07741 }
07742
07748 static void FinaliseIndustriesArray()
07749 {
07750 const GRFFile * const *end = _grf_files.End();
07751 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07752 IndustrySpec **&industryspec = (*file)->industryspec;
07753 IndustryTileSpec **&indtspec = (*file)->indtspec;
07754 if (industryspec != NULL) {
07755 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
07756 IndustrySpec *indsp = industryspec[i];
07757
07758 if (indsp != NULL && indsp->enabled) {
07759 StringID strid;
07760
07761
07762
07763 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
07764 if (strid != STR_UNDEFINED) indsp->name = strid;
07765
07766 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
07767 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
07768
07769 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
07770 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
07771
07772 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
07773 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
07774
07775 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
07776 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
07777
07778 if (indsp->station_name != STR_NULL) {
07779
07780
07781 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
07782 if (strid != STR_UNDEFINED) indsp->station_name = strid;
07783 }
07784
07785 _industry_mngr.SetEntitySpec(indsp);
07786 _loaded_newgrf_features.has_newindustries = true;
07787 }
07788 }
07789 }
07790
07791 if (indtspec != NULL) {
07792 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
07793 IndustryTileSpec *indtsp = indtspec[i];
07794 if (indtsp != NULL) {
07795 _industile_mngr.SetEntitySpec(indtsp);
07796 }
07797 }
07798 }
07799 }
07800
07801 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
07802 IndustrySpec *indsp = &_industry_specs[j];
07803 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
07804 for (uint i = 0; i < 3; i++) {
07805 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
07806 }
07807 }
07808 if (!indsp->enabled) {
07809 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
07810 }
07811 }
07812 }
07813
07819 static void FinaliseObjectsArray()
07820 {
07821 const GRFFile * const *end = _grf_files.End();
07822 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07823 ObjectSpec **&objectspec = (*file)->objectspec;
07824 if (objectspec != NULL) {
07825 for (int i = 0; i < NUM_OBJECTS; i++) {
07826 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
07827 _object_mngr.SetEntitySpec(objectspec[i]);
07828 }
07829 }
07830 }
07831 }
07832 }
07833
07839 static void FinaliseAirportsArray()
07840 {
07841 const GRFFile * const *end = _grf_files.End();
07842 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
07843 AirportSpec **&airportspec = (*file)->airportspec;
07844 if (airportspec != NULL) {
07845 for (int i = 0; i < NUM_AIRPORTS; i++) {
07846 if (airportspec[i] != NULL && airportspec[i]->enabled) {
07847 _airport_mngr.SetEntitySpec(airportspec[i]);
07848 }
07849 }
07850 }
07851
07852 AirportTileSpec **&airporttilespec = (*file)->airtspec;
07853 if (airporttilespec != NULL) {
07854 for (uint i = 0; i < NUM_AIRPORTTILES; i++) {
07855 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
07856 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
07857 }
07858 }
07859 }
07860 }
07861 }
07862
07863
07864
07865
07866
07867
07868
07869 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
07870 {
07871
07872
07873
07874
07875
07876
07877
07878
07879
07880
07881
07882
07883 static const SpecialSpriteHandler handlers[][GLS_END] = {
07884 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
07885 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
07886 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
07887 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
07888 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
07889 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
07890 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
07891 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
07892 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
07893 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
07894 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
07895 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
07896 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
07897 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
07898 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
07899 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
07900 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
07901 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
07902 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
07903 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
07904 { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
07905 };
07906
07907 GRFLocation location(_cur_grfconfig->ident.grfid, _nfo_line);
07908
07909 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
07910 if (it == _grf_line_to_action6_sprite_override.end()) {
07911
07912
07913 FioReadBlock(buf, num);
07914 } else {
07915
07916 buf = _grf_line_to_action6_sprite_override[location];
07917 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
07918
07919
07920 FioSeekTo(num, SEEK_CUR);
07921 }
07922
07923 ByteReader br(buf, buf + num);
07924 ByteReader *bufp = &br;
07925
07926 try {
07927 byte action = bufp->ReadByte();
07928
07929 if (action == 0xFF) {
07930 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
07931 GRFDataBlock(bufp);
07932 } else if (action == 0xFE) {
07933 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
07934 GRFImportBlock(bufp);
07935 } else if (action >= lengthof(handlers)) {
07936 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
07937 } else if (handlers[action][stage] == NULL) {
07938 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
07939 } else {
07940 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
07941 handlers[action][stage](bufp);
07942 }
07943 } catch (...) {
07944 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
07945 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
07946 }
07947 }
07948
07949
07950 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
07951 {
07952 const char *filename = config->filename;
07953 uint16 num;
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963
07964 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
07965 _cur_grffile = GetFileByFilename(filename);
07966 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
07967 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
07968 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
07969 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
07970 }
07971
07972 if (file_index > LAST_GRF_SLOT) {
07973 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
07974 config->status = GCS_DISABLED;
07975 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
07976 return;
07977 }
07978
07979 FioOpenFile(file_index, filename);
07980 _file_index = file_index;
07981 _palette_remap_grf[_file_index] = ((config->palette & GRFP_USE_MASK) != (_use_palette == PAL_WINDOWS));
07982
07983 _cur_grfconfig = config;
07984
07985 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
07986
07987
07988
07989
07990 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
07991 FioReadDword();
07992 } else {
07993 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
07994 return;
07995 }
07996
07997 _skip_sprites = 0;
07998 _nfo_line = 0;
07999
08000 ReusableBuffer<byte> buf;
08001
08002 while ((num = FioReadWord()) != 0) {
08003 byte type = FioReadByte();
08004 _nfo_line++;
08005
08006 if (type == 0xFF) {
08007 if (_skip_sprites == 0) {
08008 DecodeSpecialSprite(buf.Allocate(num), num, stage);
08009
08010
08011 if (_skip_sprites == -1) break;
08012
08013 continue;
08014 } else {
08015 FioSkipBytes(num);
08016 }
08017 } else {
08018 if (_skip_sprites == 0) {
08019 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
08020 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
08021 break;
08022 }
08023
08024 FioSkipBytes(7);
08025 SkipSpriteData(type, num - 8);
08026 }
08027
08028 if (_skip_sprites > 0) _skip_sprites--;
08029 }
08030 }
08031
08039 static void ActivateOldShore()
08040 {
08041
08042
08043 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
08044
08045 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
08046 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
08047 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
08048 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
08049 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4);
08050 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
08051 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
08052 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
08053 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
08054 }
08055
08056 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
08057 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
08058 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
08059 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
08060 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
08061 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
08062 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
08063 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
08064 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
08065
08066
08067
08068 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
08069 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
08070 }
08071 }
08072
08076 static void FinalisePriceBaseMultipliers()
08077 {
08078 extern const PriceBaseSpec _price_base_specs[];
08079 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
08080
08081
08082 int num_grfs = _grf_files.Length();
08083 int *grf_overrides = AllocaM(int, num_grfs);
08084 for (int i = 0; i < num_grfs; i++) {
08085 grf_overrides[i] = -1;
08086
08087 GRFFile *source = _grf_files[i];
08088 uint32 override = _grf_id_overrides[source->grfid];
08089 if (override == 0) continue;
08090
08091 GRFFile *dest = GetFileByGRFID(override);
08092 if (dest == NULL) continue;
08093
08094 grf_overrides[i] = _grf_files.FindIndex(dest);
08095 assert(grf_overrides[i] >= 0);
08096 }
08097
08098
08099 for (int i = 0; i < num_grfs; i++) {
08100 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
08101 GRFFile *source = _grf_files[i];
08102 GRFFile *dest = _grf_files[grf_overrides[i]];
08103
08104 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08105 source->grf_features |= features;
08106 dest->grf_features |= features;
08107
08108 for (Price p = PR_BEGIN; p < PR_END; p++) {
08109
08110 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
08111 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
08112 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08113 }
08114 }
08115
08116
08117 for (int i = num_grfs - 1; i >= 0; i--) {
08118 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
08119 GRFFile *source = _grf_files[i];
08120 GRFFile *dest = _grf_files[grf_overrides[i]];
08121
08122 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08123 source->grf_features |= features;
08124 dest->grf_features |= features;
08125
08126 for (Price p = PR_BEGIN; p < PR_END; p++) {
08127
08128 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
08129 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
08130 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
08131 }
08132 }
08133
08134
08135 for (int i = 0; i < num_grfs; i++) {
08136 if (grf_overrides[i] < 0) continue;
08137 GRFFile *source = _grf_files[i];
08138 GRFFile *dest = _grf_files[grf_overrides[i]];
08139
08140 uint32 features = (source->grf_features | dest->grf_features) & override_features;
08141 source->grf_features |= features;
08142 dest->grf_features |= features;
08143
08144 for (Price p = PR_BEGIN; p < PR_END; p++) {
08145 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
08146 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
08147 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
08148 }
08149 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
08150 }
08151 }
08152
08153
08154 const GRFFile * const *end = _grf_files.End();
08155 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08156 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08157 for (Price p = PR_BEGIN; p < PR_END; p++) {
08158 Price fallback_price = _price_base_specs[p].fallback_price;
08159 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08160
08161
08162 price_base_multipliers[p] = price_base_multipliers[fallback_price];
08163 }
08164 }
08165 }
08166
08167
08168 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
08169 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
08170 for (Price p = PR_BEGIN; p < PR_END; p++) {
08171 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
08172
08173 price_base_multipliers[p] = 0;
08174 } else {
08175 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
08176
08177
08178 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
08179 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
08180 price_base_multipliers[p] = 0;
08181 } else {
08182 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
08183 }
08184 }
08185 }
08186 }
08187 }
08188
08189 void InitDepotWindowBlockSizes();
08190
08191 extern void InitGRFTownGeneratorNames();
08192
08193 static void AfterLoadGRFs()
08194 {
08195 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
08196 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
08197 }
08198 _string_to_grf_mapping.clear();
08199
08200
08201 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
08202 free((*it).second);
08203 }
08204 _grf_line_to_action6_sprite_override.clear();
08205
08206
08207 FinaliseCargoArray();
08208
08209
08210 CalculateRefitMasks();
08211
08212
08213 FinaliseEngineArray();
08214
08215
08216 FinaliseCanals();
08217
08218
08219 InitDepotWindowBlockSizes();
08220
08221
08222 FinaliseHouseArray();
08223
08224
08225 FinaliseIndustriesArray();
08226
08227
08228 FinaliseObjectsArray();
08229
08230 InitializeSortedCargoSpecs();
08231
08232
08233 SortIndustryTypes();
08234
08235
08236 BuildIndustriesLegend();
08237
08238
08239 FinaliseAirportsArray();
08240 BindAirportSpecs();
08241
08242
08243 InitGRFTownGeneratorNames();
08244
08245
08246 CommitVehicleListOrderChanges();
08247
08248
08249 ActivateOldShore();
08250
08251
08252 InitRailTypes();
08253
08254 Engine *e;
08255 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
08256 if (_gted[e->index].rv_max_speed != 0) {
08257
08258 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
08259 }
08260 }
08261
08262 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
08263 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
08264 if (railtype == INVALID_RAILTYPE) {
08265
08266 e->info.climates = 0x80;
08267 } else {
08268 e->u.rail.railtype = railtype;
08269 }
08270 }
08271
08272 SetYearEngineAgingStops();
08273
08274 FinalisePriceBaseMultipliers();
08275
08276
08277 free(_gted);
08278 _grm_sprites.clear();
08279 }
08280
08281 void LoadNewGRF(uint load_index, uint file_index)
08282 {
08283
08284
08285
08286
08287 Date date = _date;
08288 Year year = _cur_year;
08289 DateFract date_fract = _date_fract;
08290 uint16 tick_counter = _tick_counter;
08291 byte display_opt = _display_opt;
08292
08293 if (_networking) {
08294 _cur_year = _settings_game.game_creation.starting_year;
08295 _date = ConvertYMDToDate(_cur_year, 0, 1);
08296 _date_fract = 0;
08297 _tick_counter = 0;
08298 _display_opt = 0;
08299 }
08300
08301 InitializeGRFSpecial();
08302
08303 ResetNewGRFData();
08304
08305
08306
08307
08308
08309
08310
08311
08312 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08313 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
08314 }
08315
08316 _cur_spriteid = load_index;
08317
08318
08319
08320
08321 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
08322
08323
08324 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08325 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
08326 }
08327
08328 uint slot = file_index;
08329
08330 _cur_stage = stage;
08331 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
08332 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
08333 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
08334
08335 if (!FioCheckFileExists(c->filename)) {
08336 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
08337 c->status = GCS_NOT_FOUND;
08338 continue;
08339 }
08340
08341 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
08342 LoadNewGRFFile(c, slot++, stage);
08343 if (stage == GLS_RESERVE) {
08344 SetBit(c->flags, GCF_RESERVED);
08345 } else if (stage == GLS_ACTIVATION) {
08346 ClrBit(c->flags, GCF_RESERVED);
08347 assert(GetFileByGRFID(c->ident.grfid) == _cur_grffile);
08348 ClearTemporaryNewGRFData(_cur_grffile);
08349 BuildCargoTranslationMap();
08350 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
08351 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
08352
08353 ClearTemporaryNewGRFData(_cur_grffile);
08354 }
08355 }
08356 }
08357
08358
08359 AfterLoadGRFs();
08360
08361
08362 _cur_year = year;
08363 _date = date;
08364 _date_fract = date_fract;
08365 _tick_counter = tick_counter;
08366 _display_opt = display_opt;
08367 }
08368
08369 bool HasGrfMiscBit(GrfMiscBit bit)
08370 {
08371 return HasBit(_misc_grf_features, bit);
08372 }