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