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
02182 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
02183 {
02184 for (int i = 0; i < size - 1; i++) {
02185 for (int j = i + 1; j < size; j++) {
02186 if (layout[i].ti.x == layout[j].ti.x &&
02187 layout[i].ti.y == layout[j].ti.y) {
02188 return false;
02189 }
02190 }
02191 }
02192 return true;
02193 }
02194
02195 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, byte **bufp, int len)
02196 {
02197 byte *buf = *bufp;
02198 ChangeInfoResult ret = CIR_SUCCESS;
02199
02200 if (indid + numinfo > NUM_INDUSTRYTYPES) {
02201 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES);
02202 return CIR_INVALID_ID;
02203 }
02204
02205 grfmsg(1, "IndustriesChangeInfo: newid %u", indid);
02206
02207
02208 if (_cur_grffile->industryspec == NULL) {
02209 _cur_grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES);
02210 }
02211
02212 for (int i = 0; i < numinfo; i++) {
02213 IndustrySpec *indsp = _cur_grffile->industryspec[indid + i];
02214
02215 if (prop != 0x08 && indsp == NULL) {
02216 grfmsg(2, "IndustriesChangeInfo: Attempt to modify undefined industry %u. Ignoring.", indid + i);
02217 return CIR_INVALID_ID;
02218 }
02219
02220 switch (prop) {
02221 case 0x08: {
02222 IndustrySpec **indspec = &_cur_grffile->industryspec[indid + i];
02223 byte subs_id = grf_load_byte(&buf);
02224
02225 if (subs_id == 0xFF) {
02226
02227
02228 _industry_specs[indid + i].enabled = false;
02229 continue;
02230 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
02231
02232 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
02233 continue;
02234 }
02235
02236
02237
02238
02239 if (*indspec == NULL) {
02240 *indspec = CallocT<IndustrySpec>(1);
02241 indsp = *indspec;
02242
02243 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
02244 indsp->enabled = true;
02245 indsp->grf_prop.local_id = indid + i;
02246 indsp->grf_prop.subst_id = subs_id;
02247 indsp->grf_prop.grffile = _cur_grffile;
02248
02249
02250 indsp->check_proc = CHECK_NOTHING;
02251 }
02252 } break;
02253
02254 case 0x09: {
02255 byte ovrid = grf_load_byte(&buf);
02256
02257
02258 if (ovrid >= NEW_INDUSTRYOFFSET) {
02259 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
02260 continue;
02261 }
02262 indsp->grf_prop.override = ovrid;
02263 _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
02264 } break;
02265
02266 case 0x0A: {
02267 indsp->num_table = grf_load_byte(&buf);
02268 uint32 defsize = grf_load_dword(&buf);
02269 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(indsp->num_table);
02270 IndustryTileTable *itt = CallocT<IndustryTileTable>(defsize);
02271 int size;
02272 IndustryTileTable *copy_from;
02273
02274 for (byte j = 0; j < indsp->num_table; j++) {
02275 for (int k = 0;; k++) {
02276 itt[k].ti.x = grf_load_byte(&buf);
02277
02278 if (itt[k].ti.x == 0xFE && k == 0) {
02279
02280 IndustryType type = grf_load_byte(&buf);
02281 byte laynbr = grf_load_byte(&buf);
02282
02283 copy_from = (IndustryTileTable*)_origin_industry_specs[type].table[laynbr];
02284 for (size = 1;; size++) {
02285 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
02286 }
02287 break;
02288 }
02289
02290 itt[k].ti.y = grf_load_byte(&buf);
02291
02292 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
02293
02294
02295 itt[k].ti.x = -0x80;
02296 itt[k].ti.y = 0;
02297 itt[k].gfx = 0;
02298
02299 size = k + 1;
02300 copy_from = itt;
02301 break;
02302 }
02303
02304 itt[k].gfx = grf_load_byte(&buf);
02305
02306 if (itt[k].gfx == 0xFE) {
02307
02308 int local_tile_id = grf_load_word(&buf);
02309
02310
02311 int tempid = _industile_mngr.GetID(local_tile_id, _cur_grffile->grfid);
02312
02313 if (tempid == INVALID_INDUSTRYTILE) {
02314 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
02315 } else {
02316
02317 itt[k].gfx = tempid;
02318 size = k + 1;
02319 copy_from = itt;
02320 }
02321 } else if (itt[k].gfx == 0xFF) {
02322 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
02323 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
02324 }
02325 }
02326
02327 if (!ValidateIndustryLayout(copy_from, size)) {
02328
02329 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
02330 indsp->num_table--;
02331 j--;
02332 } else {
02333 tile_table[j] = CallocT<IndustryTileTable>(size);
02334 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
02335 }
02336 }
02337
02338 indsp->table = tile_table;
02339 SetBit(indsp->cleanup_flag, 1);
02340 free(itt);
02341 } break;
02342
02343 case 0x0B:
02344 indsp->life_type = (IndustryLifeType)grf_load_byte(&buf);
02345 break;
02346
02347 case 0x0C:
02348 indsp->closure_text = grf_load_word(&buf);
02349 _string_to_grf_mapping[&indsp->closure_text] = _cur_grffile->grfid;
02350 break;
02351
02352 case 0x0D:
02353 indsp->production_up_text = grf_load_word(&buf);
02354 _string_to_grf_mapping[&indsp->production_up_text] = _cur_grffile->grfid;
02355 break;
02356
02357 case 0x0E:
02358 indsp->production_down_text = grf_load_word(&buf);
02359 _string_to_grf_mapping[&indsp->production_down_text] = _cur_grffile->grfid;
02360 break;
02361
02362 case 0x0F:
02363 indsp->cost_multiplier = grf_load_byte(&buf);
02364 break;
02365
02366 case 0x10:
02367 for (byte j = 0; j < 2; j++) {
02368 indsp->produced_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
02369 }
02370 break;
02371
02372 case 0x11:
02373 for (byte j = 0; j < 3; j++) {
02374 indsp->accepts_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
02375 }
02376 grf_load_byte(&buf);
02377 break;
02378
02379 case 0x12:
02380 case 0x13:
02381 indsp->production_rate[prop - 0x12] = grf_load_byte(&buf);
02382 break;
02383
02384 case 0x14:
02385 indsp->minimal_cargo = grf_load_byte(&buf);
02386 break;
02387
02388 case 0x15: {
02389 indsp->number_of_sounds = grf_load_byte(&buf);
02390 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
02391
02392 for (uint8 j = 0; j < indsp->number_of_sounds; j++) sounds[j] = grf_load_byte(&buf);
02393 indsp->random_sounds = sounds;
02394 SetBit(indsp->cleanup_flag, 0);
02395 } break;
02396
02397 case 0x16:
02398 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = grf_load_byte(&buf);
02399 break;
02400
02401 case 0x17:
02402 indsp->appear_creation[_settings_game.game_creation.landscape] = grf_load_byte(&buf);
02403 break;
02404
02405 case 0x18:
02406 indsp->appear_ingame[_settings_game.game_creation.landscape] = grf_load_byte(&buf);
02407 break;
02408
02409 case 0x19:
02410 indsp->map_colour = MapDOSColour(grf_load_byte(&buf));
02411 break;
02412
02413 case 0x1A:
02414 indsp->behaviour = (IndustryBehaviour)grf_load_dword(&buf);
02415 break;
02416
02417 case 0x1B:
02418 indsp->new_industry_text = grf_load_word(&buf);
02419 _string_to_grf_mapping[&indsp->new_industry_text] = _cur_grffile->grfid;
02420 break;
02421
02422 case 0x1C:
02423 case 0x1D:
02424 case 0x1E: {
02425 uint32 multiples = grf_load_dword(&buf);
02426 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
02427 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
02428 } break;
02429
02430 case 0x1F:
02431 indsp->name = grf_load_word(&buf);
02432 _string_to_grf_mapping[&indsp->name] = _cur_grffile->grfid;
02433 break;
02434
02435 case 0x20:
02436 indsp->prospecting_chance = grf_load_dword(&buf);
02437 break;
02438
02439 case 0x21:
02440 case 0x22: {
02441 byte aflag = grf_load_byte(&buf);
02442 SB(indsp->callback_flags, (prop - 0x21) * 8, 8, aflag);
02443 } break;
02444
02445 case 0x23:
02446 indsp->removal_cost_multiplier = grf_load_dword(&buf);
02447 break;
02448
02449 case 0x24:
02450 indsp->station_name = grf_load_word(&buf);
02451 _string_to_grf_mapping[&indsp->station_name] = _cur_grffile->grfid;
02452 break;
02453
02454 default:
02455 ret = CIR_UNKNOWN;
02456 break;
02457 }
02458 }
02459
02460 *bufp = buf;
02461 return ret;
02462 }
02463
02464 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
02465 {
02466 switch (cir) {
02467 default: NOT_REACHED();
02468
02469 case CIR_SUCCESS:
02470 return false;
02471
02472 case CIR_UNHANDLED:
02473 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
02474 return false;
02475
02476 case CIR_UNKNOWN:
02477 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
02478
02479
02480 case CIR_INVALID_ID:
02481
02482 _skip_sprites = -1;
02483 _cur_grfconfig->status = GCS_DISABLED;
02484 _cur_grfconfig->error = CallocT<GRFError>(1);
02485 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
02486 _cur_grfconfig->error->message = (cir == CIR_INVALID_ID) ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY;
02487 return true;
02488 }
02489 }
02490
02491
02492 static void FeatureChangeInfo(byte *buf, size_t len)
02493 {
02494 byte *bufend = buf + len;
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509 static const VCI_Handler handler[] = {
02510 RailVehicleChangeInfo,
02511 RoadVehicleChangeInfo,
02512 ShipVehicleChangeInfo,
02513 AircraftVehicleChangeInfo,
02514 StationChangeInfo,
02515 CanalChangeInfo,
02516 BridgeChangeInfo,
02517 TownHouseChangeInfo,
02518 GlobalVarChangeInfo,
02519 IndustrytilesChangeInfo,
02520 IndustriesChangeInfo,
02521 NULL,
02522 SoundEffectChangeInfo,
02523 };
02524
02525 if (!check_length(len, 6, "FeatureChangeInfo")) return;
02526 buf++;
02527 uint8 feature = grf_load_byte(&buf);
02528 uint8 numprops = grf_load_byte(&buf);
02529 uint numinfo = grf_load_byte(&buf);
02530 uint engine = grf_load_extended(&buf);
02531
02532 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
02533 feature, numprops, engine, numinfo);
02534
02535 if (feature >= lengthof(handler) || handler[feature] == NULL) {
02536 grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
02537 return;
02538 }
02539
02540 while (numprops-- && buf < bufend) {
02541 uint8 prop = grf_load_byte(&buf);
02542
02543 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, &buf, bufend - buf);
02544 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
02545 }
02546 }
02547
02548
02549 static void SafeChangeInfo(byte *buf, size_t len)
02550 {
02551 if (!check_length(len, 6, "SafeChangeInfo")) return;
02552 buf++;
02553 uint8 feature = grf_load_byte(&buf);
02554 uint8 numprops = grf_load_byte(&buf);
02555 uint numinfo = grf_load_byte(&buf);
02556 grf_load_extended(&buf);
02557
02558 if (feature == GSF_BRIDGE && numprops == 1) {
02559 uint8 prop = grf_load_byte(&buf);
02560
02561
02562 if (prop == 0x0D) return;
02563 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
02564 uint8 prop = grf_load_byte(&buf);
02565
02566 if (prop == 0x11) {
02567 bool is_safe = true;
02568 for (uint i = 0; i < numinfo; i++) {
02569 uint32 s = grf_load_dword(&buf);
02570 grf_load_dword(&buf);
02571 const GRFConfig *grfconfig = GetGRFConfig(s);
02572 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
02573 is_safe = false;
02574 break;
02575 }
02576 }
02577 if (is_safe) return;
02578 }
02579 }
02580
02581 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
02582
02583
02584 _skip_sprites = -1;
02585 }
02586
02587
02588 static void ReserveChangeInfo(byte *buf, size_t len)
02589 {
02590 byte *bufend = buf + len;
02591
02592 if (!check_length(len, 6, "ReserveChangeInfo")) return;
02593 buf++;
02594 uint8 feature = grf_load_byte(&buf);
02595
02596 if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR) return;
02597
02598 uint8 numprops = grf_load_byte(&buf);
02599 uint8 numinfo = grf_load_byte(&buf);
02600 uint8 index = grf_load_extended(&buf);
02601
02602 while (numprops-- && buf < bufend) {
02603 uint8 prop = grf_load_byte(&buf);
02604 ChangeInfoResult cir = CIR_SUCCESS;
02605
02606 switch (feature) {
02607 default: NOT_REACHED();
02608 case GSF_CARGOS:
02609 cir = CargoChangeInfo(index, numinfo, prop, &buf, bufend - buf);
02610 break;
02611
02612 case GSF_GLOBALVAR:
02613 cir = GlobalVarReserveInfo(index, numinfo, prop, &buf, bufend - buf);
02614 break;
02615 }
02616
02617 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
02618 }
02619 }
02620
02626 static const SpriteGroup *NewCallBackResultSpriteGroup(uint16 value)
02627 {
02628 SpriteGroup *group = AllocateSpriteGroup();
02629
02630 group->type = SGT_CALLBACK;
02631
02632
02633
02634 if ((value >> 8) == 0xFF) {
02635 value &= ~0xFF00;
02636 } else {
02637 value &= ~0x8000;
02638 }
02639
02640 group->g.callback.result = value;
02641
02642 return group;
02643 }
02644
02651 static const SpriteGroup *NewResultSpriteGroup(SpriteID sprite, byte num_sprites)
02652 {
02653 SpriteGroup *group = AllocateSpriteGroup();
02654 group->type = SGT_RESULT;
02655 group->g.result.sprite = sprite;
02656 group->g.result.num_sprites = num_sprites;
02657 return group;
02658 }
02659
02660
02661 static void NewSpriteSet(byte *buf, size_t len)
02662 {
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675 if (!check_length(len, 4, "NewSpriteSet")) return;
02676 buf++;
02677 uint8 feature = grf_load_byte(&buf);
02678 uint8 num_sets = grf_load_byte(&buf);
02679 uint16 num_ents = grf_load_extended(&buf);
02680
02681 _cur_grffile->spriteset_start = _cur_spriteid;
02682 _cur_grffile->spriteset_feature = feature;
02683 _cur_grffile->spriteset_numsets = num_sets;
02684 _cur_grffile->spriteset_numents = num_ents;
02685
02686 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
02687 _cur_spriteid, feature, num_sets, num_ents, num_sets * num_ents
02688 );
02689
02690 for (int i = 0; i < num_sets * num_ents; i++) {
02691 _nfo_line++;
02692 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
02693 }
02694 }
02695
02696
02697 static void SkipAct1(byte *buf, size_t len)
02698 {
02699 if (!check_length(len, 4, "SkipAct1")) return;
02700 buf++;
02701 grf_load_byte(&buf);
02702 uint8 num_sets = grf_load_byte(&buf);
02703 uint16 num_ents = grf_load_extended(&buf);
02704
02705 _skip_sprites = num_sets * num_ents;
02706
02707 grfmsg(3, "SkipAct1: Skipping %d sprites", _skip_sprites);
02708 }
02709
02710
02711
02712 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
02713 {
02714 if (HasBit(groupid, 15)) return NewCallBackResultSpriteGroup(groupid);
02715
02716 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
02717 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
02718 return NULL;
02719 }
02720
02721 return _cur_grffile->spritegroups[groupid];
02722 }
02723
02724
02725 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
02726 {
02727 if (HasBit(spriteid, 15)) return NewCallBackResultSpriteGroup(spriteid);
02728
02729 if (spriteid >= _cur_grffile->spriteset_numsets) {
02730 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
02731 return NULL;
02732 }
02733
02734
02735
02736
02737 if (_cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites > _cur_spriteid) {
02738 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Real Sprite IDs 0x%04X - 0x%04X do not (all) exist (max 0x%04X), leaving empty",
02739 setid, type,
02740 _cur_grffile->spriteset_start + spriteid * num_sprites,
02741 _cur_grffile->spriteset_start + spriteid * num_sprites + num_sprites - 1, _cur_spriteid - 1);
02742 return NULL;
02743 }
02744
02745 if (feature != _cur_grffile->spriteset_feature) {
02746 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set feature 0x%02X does not match action feature 0x%02X, skipping",
02747 setid, type,
02748 _cur_grffile->spriteset_feature, feature);
02749 return NULL;
02750 }
02751
02752 return NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteid * num_sprites, num_sprites);
02753 }
02754
02755
02756 static void NewSpriteGroup(byte *buf, size_t len)
02757 {
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768 SpriteGroup *group = NULL;
02769 byte *bufend = buf + len;
02770
02771 if (!check_length(len, 5, "NewSpriteGroup")) return;
02772 buf++;
02773
02774 uint8 feature = grf_load_byte(&buf);
02775 uint8 setid = grf_load_byte(&buf);
02776 uint8 type = grf_load_byte(&buf);
02777
02778 if (setid >= _cur_grffile->spritegroups_count) {
02779
02780 _cur_grffile->spritegroups = ReallocT(_cur_grffile->spritegroups, setid + 1);
02781
02782 for (; _cur_grffile->spritegroups_count < (setid + 1); _cur_grffile->spritegroups_count++)
02783 _cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
02784 }
02785
02786 switch (type) {
02787
02788 case 0x81:
02789 case 0x82:
02790 case 0x85:
02791 case 0x86:
02792 case 0x89:
02793 case 0x8A:
02794 {
02795 byte varadjust;
02796 byte varsize;
02797
02798
02799 if (!check_length(bufend - buf, 1, "NewSpriteGroup (Deterministic) (1)")) return;
02800
02801 group = AllocateSpriteGroup();
02802 group->type = SGT_DETERMINISTIC;
02803 group->g.determ.var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
02804
02805 switch (GB(type, 2, 2)) {
02806 default: NOT_REACHED();
02807 case 0: group->g.determ.size = DSG_SIZE_BYTE; varsize = 1; break;
02808 case 1: group->g.determ.size = DSG_SIZE_WORD; varsize = 2; break;
02809 case 2: group->g.determ.size = DSG_SIZE_DWORD; varsize = 4; break;
02810 }
02811
02812 if (!check_length(bufend - buf, 5 + varsize, "NewSpriteGroup (Deterministic) (2)")) return;
02813
02814
02815
02816 do {
02817 DeterministicSpriteGroupAdjust *adjust;
02818
02819 if (group->g.determ.num_adjusts > 0) {
02820 if (!check_length(bufend - buf, 2 + varsize + 3, "NewSpriteGroup (Deterministic) (3)")) return;
02821 }
02822
02823 group->g.determ.num_adjusts++;
02824 group->g.determ.adjusts = ReallocT(group->g.determ.adjusts, group->g.determ.num_adjusts);
02825
02826 adjust = &group->g.determ.adjusts[group->g.determ.num_adjusts - 1];
02827
02828
02829 adjust->operation = group->g.determ.num_adjusts == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)grf_load_byte(&buf);
02830 adjust->variable = grf_load_byte(&buf);
02831 if (adjust->variable == 0x7E) {
02832
02833 adjust->subroutine = GetGroupFromGroupID(setid, type, grf_load_byte(&buf));
02834 } else {
02835 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? grf_load_byte(&buf) : 0;
02836 }
02837
02838 varadjust = grf_load_byte(&buf);
02839 adjust->shift_num = GB(varadjust, 0, 5);
02840 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
02841 adjust->and_mask = grf_load_var(varsize, &buf);
02842
02843 if (adjust->type != DSGA_TYPE_NONE) {
02844 adjust->add_val = grf_load_var(varsize, &buf);
02845 adjust->divmod_val = grf_load_var(varsize, &buf);
02846 } else {
02847 adjust->add_val = 0;
02848 adjust->divmod_val = 0;
02849 }
02850
02851
02852 } while (HasBit(varadjust, 5));
02853
02854 group->g.determ.num_ranges = grf_load_byte(&buf);
02855 if (group->g.determ.num_ranges > 0) group->g.determ.ranges = CallocT<DeterministicSpriteGroupRange>(group->g.determ.num_ranges);
02856
02857 if (!check_length(bufend - buf, 2 + (2 + 2 * varsize) * group->g.determ.num_ranges, "NewSpriteGroup (Deterministic)")) return;
02858
02859 for (uint i = 0; i < group->g.determ.num_ranges; i++) {
02860 group->g.determ.ranges[i].group = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
02861 group->g.determ.ranges[i].low = grf_load_var(varsize, &buf);
02862 group->g.determ.ranges[i].high = grf_load_var(varsize, &buf);
02863 }
02864
02865 group->g.determ.default_group = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
02866 break;
02867 }
02868
02869
02870 case 0x80:
02871 case 0x83:
02872 case 0x84:
02873 {
02874 if (!check_length(bufend - buf, HasBit(type, 2) ? 8 : 7, "NewSpriteGroup (Randomized) (1)")) return;
02875
02876 group = AllocateSpriteGroup();
02877 group->type = SGT_RANDOMIZED;
02878 group->g.random.var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
02879
02880 if (HasBit(type, 2)) {
02881 if (feature <= GSF_AIRCRAFT) group->g.random.var_scope = VSG_SCOPE_RELATIVE;
02882 group->g.random.count = grf_load_byte(&buf);
02883 }
02884
02885 uint8 triggers = grf_load_byte(&buf);
02886 group->g.random.triggers = GB(triggers, 0, 7);
02887 group->g.random.cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
02888 group->g.random.lowest_randbit = grf_load_byte(&buf);
02889 group->g.random.num_groups = grf_load_byte(&buf);
02890 group->g.random.groups = CallocT<const SpriteGroup*>(group->g.random.num_groups);
02891
02892 if (!check_length(bufend - buf, 2 * group->g.random.num_groups, "NewSpriteGroup (Randomized) (2)")) return;
02893
02894 for (uint i = 0; i < group->g.random.num_groups; i++) {
02895 group->g.random.groups[i] = GetGroupFromGroupID(setid, type, grf_load_word(&buf));
02896 }
02897
02898 break;
02899 }
02900
02901
02902 default:
02903 {
02904
02905
02906 switch (feature) {
02907 case GSF_TRAIN:
02908 case GSF_ROAD:
02909 case GSF_SHIP:
02910 case GSF_AIRCRAFT:
02911 case GSF_STATION:
02912 case GSF_CANAL:
02913 case GSF_CARGOS:
02914 {
02915 byte sprites = _cur_grffile->spriteset_numents;
02916 byte num_loaded = type;
02917 byte num_loading = grf_load_byte(&buf);
02918
02919 if (_cur_grffile->spriteset_start == 0) {
02920 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
02921 return;
02922 }
02923
02924 if (!check_length(bufend - buf, 2 * num_loaded + 2 * num_loading, "NewSpriteGroup (Real) (1)")) return;
02925
02926 group = AllocateSpriteGroup();
02927 group->type = SGT_REAL;
02928
02929 group->g.real.num_loaded = num_loaded;
02930 group->g.real.num_loading = num_loading;
02931 if (num_loaded > 0) group->g.real.loaded = CallocT<const SpriteGroup*>(num_loaded);
02932 if (num_loading > 0) group->g.real.loading = CallocT<const SpriteGroup*>(num_loading);
02933
02934 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u views, %u loaded, %u loading",
02935 setid, sprites, num_loaded, num_loading);
02936
02937 for (uint i = 0; i < num_loaded; i++) {
02938 uint16 spriteid = grf_load_word(&buf);
02939 group->g.real.loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
02940 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
02941 }
02942
02943 for (uint i = 0; i < num_loading; i++) {
02944 uint16 spriteid = grf_load_word(&buf);
02945 group->g.real.loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid, sprites);
02946 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
02947 }
02948
02949 break;
02950 }
02951
02952 case GSF_TOWNHOUSE:
02953 case GSF_INDUSTRYTILES: {
02954 byte sprites = _cur_grffile->spriteset_numents;
02955 byte num_sprites = max((uint8)1, type);
02956 uint i;
02957
02958 group = AllocateSpriteGroup();
02959 group->type = SGT_TILELAYOUT;
02960 group->g.layout.num_sprites = sprites;
02961 group->g.layout.dts = CallocT<DrawTileSprites>(1);
02962
02963
02964 group->g.layout.dts->ground.sprite = grf_load_word(&buf);
02965 group->g.layout.dts->ground.pal = grf_load_word(&buf);
02966
02967
02968 MapSpriteMappingRecolour(&group->g.layout.dts->ground);
02969
02970 if (HasBit(group->g.layout.dts->ground.pal, 15)) {
02971
02972
02973 SpriteID sprite = _cur_grffile->spriteset_start + GB(group->g.layout.dts->ground.sprite, 0, 14) * sprites;
02974 SB(group->g.layout.dts->ground.sprite, 0, SPRITE_WIDTH, sprite);
02975 ClrBit(group->g.layout.dts->ground.pal, 15);
02976 }
02977
02978 group->g.layout.dts->seq = CallocT<DrawTileSeqStruct>(num_sprites + 1);
02979
02980 for (i = 0; i < num_sprites; i++) {
02981 DrawTileSeqStruct *seq = (DrawTileSeqStruct*)&group->g.layout.dts->seq[i];
02982
02983 seq->image.sprite = grf_load_word(&buf);
02984 seq->image.pal = grf_load_word(&buf);
02985 seq->delta_x = grf_load_byte(&buf);
02986 seq->delta_y = grf_load_byte(&buf);
02987
02988 MapSpriteMappingRecolour(&seq->image);
02989
02990 if (HasBit(seq->image.pal, 15)) {
02991
02992
02993 SpriteID sprite = _cur_grffile->spriteset_start + GB(seq->image.sprite, 0, 14) * sprites;
02994 SB(seq->image.sprite, 0, SPRITE_WIDTH, sprite);
02995 ClrBit(seq->image.pal, 15);
02996 }
02997
02998 if (type > 0) {
02999 seq->delta_z = grf_load_byte(&buf);
03000 if ((byte)seq->delta_z == 0x80) continue;
03001 }
03002
03003 seq->size_x = grf_load_byte(&buf);
03004 seq->size_y = grf_load_byte(&buf);
03005 seq->size_z = grf_load_byte(&buf);
03006 }
03007
03008
03009 ((DrawTileSeqStruct*)group->g.layout.dts->seq)[i].delta_x = (byte)0x80;
03010
03011 break;
03012 }
03013
03014 case GSF_INDUSTRIES: {
03015 if (type > 1) {
03016 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
03017 break;
03018 }
03019
03020 group = AllocateSpriteGroup();
03021 group->type = SGT_INDUSTRY_PRODUCTION;
03022 group->g.indprod.version = type;
03023 if (type == 0) {
03024 for (uint i = 0; i < 3; i++) {
03025 group->g.indprod.substract_input[i] = grf_load_word(&buf);
03026 }
03027 for (uint i = 0; i < 2; i++) {
03028 group->g.indprod.add_output[i] = grf_load_word(&buf);
03029 }
03030 group->g.indprod.again = grf_load_byte(&buf);
03031 } else {
03032 for (uint i = 0; i < 3; i++) {
03033 group->g.indprod.substract_input[i] = grf_load_byte(&buf);
03034 }
03035 for (uint i = 0; i < 2; i++) {
03036 group->g.indprod.add_output[i] = grf_load_byte(&buf);
03037 }
03038 group->g.indprod.again = grf_load_byte(&buf);
03039 }
03040 break;
03041 }
03042
03043
03044 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
03045 }
03046 }
03047 }
03048
03049 _cur_grffile->spritegroups[setid] = group;
03050 }
03051
03052 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
03053 {
03054
03055 if (feature == GSF_STATION && ctype == 0xFE) return CT_DEFAULT_NA;
03056 if (ctype == 0xFF) return CT_PURCHASE;
03057
03058 if (_cur_grffile->cargo_max == 0) {
03059
03060 if (ctype >= 32) {
03061 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
03062 return CT_INVALID;
03063 }
03064
03065 for (CargoID c = 0; c < NUM_CARGO; c++) {
03066 const CargoSpec *cs = GetCargo(c);
03067 if (!cs->IsValid()) continue;
03068
03069 if (cs->bitnum == ctype) {
03070 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, c);
03071 return c;
03072 }
03073 }
03074
03075 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
03076 return CT_INVALID;
03077 }
03078
03079
03080 if (ctype >= _cur_grffile->cargo_max) {
03081 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur_grffile->cargo_max - 1);
03082 return CT_INVALID;
03083 }
03084
03085
03086 CargoLabel cl = _cur_grffile->cargo_list[ctype];
03087 if (cl == 0) {
03088 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
03089 return CT_INVALID;
03090 }
03091
03092 ctype = GetCargoIDByLabel(cl);
03093 if (ctype == CT_INVALID) {
03094 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));
03095 return CT_INVALID;
03096 }
03097
03098 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);
03099 return ctype;
03100 }
03101
03102
03103 static bool IsValidGroupID(uint16 groupid, const char *function)
03104 {
03105 if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
03106 grfmsg(1, "%s: Spriteset 0x%04X out of range (maximum 0x%02X) or empty, skipping.", function, groupid, _cur_grffile->spritegroups_count - 1);
03107 return false;
03108 }
03109
03110 return true;
03111 }
03112
03113 static void VehicleMapSpriteGroup(byte *buf, byte feature, uint8 idcount)
03114 {
03115 static EngineID *last_engines;
03116 static uint last_engines_count;
03117 bool wagover = false;
03118
03119
03120 if (HasBit(idcount, 7)) {
03121 wagover = true;
03122
03123 idcount = GB(idcount, 0, 7);
03124
03125 if (last_engines_count == 0) {
03126 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
03127 return;
03128 }
03129
03130 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
03131 last_engines_count, idcount);
03132 } else {
03133 if (last_engines_count != idcount) {
03134 last_engines = ReallocT(last_engines, idcount);
03135 last_engines_count = idcount;
03136 }
03137 }
03138
03139 EngineID *engines = AllocaM(EngineID, idcount);
03140 for (uint i = 0; i < idcount; i++) {
03141 engines[i] = GetNewEngine(_cur_grffile, (VehicleType)feature, grf_load_extended(&buf))->index;
03142 if (!wagover) last_engines[i] = engines[i];
03143 }
03144
03145 uint8 cidcount = grf_load_byte(&buf);
03146 for (uint c = 0; c < cidcount; c++) {
03147 uint8 ctype = grf_load_byte(&buf);
03148 uint16 groupid = grf_load_word(&buf);
03149 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
03150
03151 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
03152
03153 ctype = TranslateCargo(feature, ctype);
03154 if (ctype == CT_INVALID) continue;
03155
03156 for (uint i = 0; i < idcount; i++) {
03157 EngineID engine = engines[i];
03158
03159 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
03160
03161 if (wagover) {
03162 SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03163 } else {
03164 SetCustomEngineSprites(engine, ctype, _cur_grffile->spritegroups[groupid]);
03165 }
03166 }
03167 }
03168
03169 uint16 groupid = grf_load_word(&buf);
03170 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
03171
03172 grfmsg(8, "-- Default group id 0x%04X", groupid);
03173
03174 for (uint i = 0; i < idcount; i++) {
03175 EngineID engine = engines[i];
03176
03177 if (wagover) {
03178 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
03179 } else {
03180 SetCustomEngineSprites(engine, CT_DEFAULT, _cur_grffile->spritegroups[groupid]);
03181 SetEngineGRF(engine, _cur_grffile);
03182 }
03183 }
03184 }
03185
03186
03187 static void CanalMapSpriteGroup(byte *buf, uint8 idcount)
03188 {
03189 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
03190 for (uint i = 0; i < idcount; i++) {
03191 cfs[i] = (CanalFeature)grf_load_byte(&buf);
03192 }
03193
03194 uint8 cidcount = grf_load_byte(&buf);
03195 buf += cidcount * 3;
03196
03197 uint16 groupid = grf_load_word(&buf);
03198 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
03199
03200 for (uint i = 0; i < idcount; i++) {
03201 CanalFeature cf = cfs[i];
03202
03203 if (cf >= CF_END) {
03204 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
03205 continue;
03206 }
03207
03208 _water_feature[cf].grffile = _cur_grffile;
03209 _water_feature[cf].group = _cur_grffile->spritegroups[groupid];
03210 }
03211 }
03212
03213
03214 static void StationMapSpriteGroup(byte *buf, uint8 idcount)
03215 {
03216 uint8 *stations = AllocaM(uint8, idcount);
03217 for (uint i = 0; i < idcount; i++) {
03218 stations[i] = grf_load_byte(&buf);
03219 }
03220
03221 uint8 cidcount = grf_load_byte(&buf);
03222 for (uint c = 0; c < cidcount; c++) {
03223 uint8 ctype = grf_load_byte(&buf);
03224 uint16 groupid = grf_load_word(&buf);
03225 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
03226
03227 ctype = TranslateCargo(GSF_STATION, ctype);
03228 if (ctype == CT_INVALID) continue;
03229
03230 for (uint i = 0; i < idcount; i++) {
03231 StationSpec *statspec = _cur_grffile->stations[stations[i]];
03232
03233 if (statspec == NULL) {
03234 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03235 continue;
03236 }
03237
03238 statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
03239 }
03240 }
03241
03242 uint16 groupid = grf_load_word(&buf);
03243 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
03244
03245 for (uint i = 0; i < idcount; i++) {
03246 StationSpec *statspec = _cur_grffile->stations[stations[i]];
03247
03248 if (statspec == NULL) {
03249 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
03250 continue;
03251 }
03252
03253 statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
03254 statspec->grffile = _cur_grffile;
03255 statspec->localidx = stations[i];
03256 SetCustomStationSpec(statspec);
03257 }
03258 }
03259
03260
03261 static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount)
03262 {
03263 uint8 *houses = AllocaM(uint8, idcount);
03264 for (uint i = 0; i < idcount; i++) {
03265 houses[i] = grf_load_byte(&buf);
03266 }
03267
03268
03269 uint8 cidcount = grf_load_byte(&buf);
03270 buf += cidcount * 3;
03271
03272 uint16 groupid = grf_load_word(&buf);
03273 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
03274
03275 for (uint i = 0; i < idcount; i++) {
03276 HouseSpec *hs = _cur_grffile->housespec[houses[i]];
03277
03278 if (hs == NULL) {
03279 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
03280 continue;
03281 }
03282
03283 hs->spritegroup = _cur_grffile->spritegroups[groupid];
03284 }
03285 }
03286
03287 static void IndustryMapSpriteGroup(byte *buf, uint8 idcount)
03288 {
03289 uint8 *industries = AllocaM(uint8, idcount);
03290 for (uint i = 0; i < idcount; i++) {
03291 industries[i] = grf_load_byte(&buf);
03292 }
03293
03294
03295 uint8 cidcount = grf_load_byte(&buf);
03296 buf += cidcount * 3;
03297
03298 uint16 groupid = grf_load_word(&buf);
03299 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
03300
03301 for (uint i = 0; i < idcount; i++) {
03302 IndustrySpec *indsp = _cur_grffile->industryspec[industries[i]];
03303
03304 if (indsp == NULL) {
03305 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
03306 continue;
03307 }
03308
03309 indsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03310 }
03311 }
03312
03313 static void IndustrytileMapSpriteGroup(byte *buf, uint8 idcount)
03314 {
03315 uint8 *indtiles = AllocaM(uint8, idcount);
03316 for (uint i = 0; i < idcount; i++) {
03317 indtiles[i] = grf_load_byte(&buf);
03318 }
03319
03320
03321 uint8 cidcount = grf_load_byte(&buf);
03322 buf += cidcount * 3;
03323
03324 uint16 groupid = grf_load_word(&buf);
03325 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
03326
03327 for (uint i = 0; i < idcount; i++) {
03328 IndustryTileSpec *indtsp = _cur_grffile->indtspec[indtiles[i]];
03329
03330 if (indtsp == NULL) {
03331 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
03332 continue;
03333 }
03334
03335 indtsp->grf_prop.spritegroup = _cur_grffile->spritegroups[groupid];
03336 }
03337 }
03338
03339 static void CargoMapSpriteGroup(byte *buf, uint8 idcount)
03340 {
03341 CargoID *cargos = AllocaM(CargoID, idcount);
03342 for (uint i = 0; i < idcount; i++) {
03343 cargos[i] = grf_load_byte(&buf);
03344 }
03345
03346
03347 uint8 cidcount = grf_load_byte(&buf);
03348 buf += cidcount * 3;
03349
03350 uint16 groupid = grf_load_word(&buf);
03351 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
03352
03353 for (uint i = 0; i < idcount; i++) {
03354 CargoID cid = cargos[i];
03355
03356 if (cid >= NUM_CARGO) {
03357 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
03358 continue;
03359 }
03360
03361 CargoSpec *cs = &_cargo[cid];
03362 cs->grffile = _cur_grffile;
03363 cs->group = _cur_grffile->spritegroups[groupid];
03364 }
03365 }
03366
03367
03368
03369 static void FeatureMapSpriteGroup(byte *buf, size_t len)
03370 {
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385 if (_cur_grffile->spritegroups == 0) {
03386 grfmsg(1, "FeatureMapSpriteGroup: No sprite groups to work on! Skipping");
03387 return;
03388 }
03389
03390 if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
03391
03392 buf++;
03393 uint8 feature = grf_load_byte(&buf);
03394 uint8 idcount = grf_load_byte(&buf);
03395
03396
03397 if (idcount == 0) {
03398
03399 grf_load_byte(&buf);
03400 uint16 groupid = grf_load_word(&buf);
03401
03402 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
03403
03404 AddGenericCallback(feature, _cur_grffile, _cur_grffile->spritegroups[groupid]);
03405 return;
03406 }
03407
03408 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
03409
03410 switch (feature) {
03411 case GSF_TRAIN:
03412 case GSF_ROAD:
03413 case GSF_SHIP:
03414 case GSF_AIRCRAFT:
03415 VehicleMapSpriteGroup(buf, feature, idcount);
03416 return;
03417
03418 case GSF_CANAL:
03419 CanalMapSpriteGroup(buf, idcount);
03420 return;
03421
03422 case GSF_STATION:
03423 StationMapSpriteGroup(buf, idcount);
03424 return;
03425
03426 case GSF_TOWNHOUSE:
03427 TownHouseMapSpriteGroup(buf, idcount);
03428 return;
03429
03430 case GSF_INDUSTRIES:
03431 IndustryMapSpriteGroup(buf, idcount);
03432 return;
03433
03434 case GSF_INDUSTRYTILES:
03435 IndustrytileMapSpriteGroup(buf, idcount);
03436 return;
03437
03438 case GSF_CARGOS:
03439 CargoMapSpriteGroup(buf, idcount);
03440 return;
03441
03442 default:
03443 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
03444 return;
03445 }
03446 }
03447
03448
03449 static void FeatureNewName(byte *buf, size_t len)
03450 {
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467 bool new_scheme = _cur_grffile->grf_version >= 7;
03468
03469 if (!check_length(len, 6, "FeatureNewName")) return;
03470 buf++;
03471 uint8 feature = grf_load_byte(&buf);
03472 uint8 lang = grf_load_byte(&buf);
03473 uint8 num = grf_load_byte(&buf);
03474 bool generic = HasBit(lang, 7);
03475 uint16 id;
03476 if (generic) {
03477 id = grf_load_word(&buf);
03478 } else if (feature <= GSF_AIRCRAFT) {
03479 id = grf_load_extended(&buf);
03480 } else {
03481 id = grf_load_byte(&buf);
03482 }
03483
03484 ClrBit(lang, 7);
03485
03486 uint16 endid = id + num;
03487
03488 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
03489 id, endid, feature, lang);
03490
03491 len -= generic ? 6 : 5;
03492
03493 for (; id < endid && len > 0; id++) {
03494 const char *name = grf_load_string(&buf, len);
03495 size_t name_length = strlen(name) + 1;
03496
03497 len -= (int)name_length;
03498
03499 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
03500
03501 switch (feature) {
03502 case GSF_TRAIN:
03503 case GSF_ROAD:
03504 case GSF_SHIP:
03505 case GSF_AIRCRAFT:
03506 if (!generic) {
03507 Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC));
03508 if (e == NULL) break;
03509 StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, name, e->info.string_id);
03510 e->info.string_id = string;
03511 } else {
03512 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03513 }
03514 break;
03515
03516 case GSF_INDUSTRIES: {
03517 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03518 break;
03519 }
03520
03521 case GSF_TOWNHOUSE:
03522 default:
03523 switch (GB(id, 8, 8)) {
03524 case 0xC4:
03525 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03526 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03527 } else {
03528 StationClassID sclass = _cur_grffile->stations[GB(id, 0, 8)]->sclass;
03529 SetStationClassName(sclass, AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED));
03530 }
03531 break;
03532
03533 case 0xC5:
03534 if (_cur_grffile->stations == NULL || _cur_grffile->stations[GB(id, 0, 8)] == NULL) {
03535 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
03536 } else {
03537 _cur_grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03538 }
03539 break;
03540
03541 case 0xC9:
03542 if (_cur_grffile->housespec == NULL || _cur_grffile->housespec[GB(id, 0, 8)] == NULL) {
03543 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
03544 } else {
03545 _cur_grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03546 }
03547 break;
03548
03549 case 0xD0:
03550 case 0xD1:
03551 case 0xD2:
03552 case 0xD3:
03553 case 0xDC:
03554 AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, name, STR_UNDEFINED);
03555 break;
03556
03557 default:
03558 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03559 break;
03560 }
03561 break;
03562
03563 #if 0
03564 case GSF_CANAL :
03565 case GSF_BRIDGE :
03566 AddGRFString(_cur_spriteid, id, lang, name);
03567 switch (GB(id, 8, 8)) {
03568 case 0xC9:
03569 default:
03570 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
03571 }
03572 break;
03573
03574 default :
03575 grfmsg(7, "FeatureNewName: Unsupported feature (0x%02X)", feature);
03576 break;
03577 #endif
03578 }
03579 }
03580 }
03581
03590 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
03591 {
03592
03593 if (offset >= max_sprites) {
03594 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
03595 uint orig_num = num;
03596 num = 0;
03597 return orig_num;
03598 }
03599
03600 if (offset + num > max_sprites) {
03601 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
03602 uint orig_num = num;
03603 num = max(max_sprites - offset, 0);
03604 return orig_num - num;
03605 }
03606
03607 return 0;
03608 }
03609
03610
03611 static void GraphicsNew(byte *buf, size_t len)
03612 {
03613
03614
03615
03616
03617
03618
03619
03620 enum Action5BlockType {
03621 A5BLOCK_FIXED,
03622 A5BLOCK_ALLOW_OFFSET,
03623 A5BLOCK_INVALID,
03624 };
03625 struct Action5Type {
03626 Action5BlockType block_type;
03627 SpriteID sprite_base;
03628 uint16 min_sprites;
03629 uint16 max_sprites;
03630 const char *name;
03631 };
03632
03633 static const Action5Type action5_types[] = {
03634
03635 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
03636 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
03637 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
03638 { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
03639 { A5BLOCK_FIXED, SPR_SIGNALS_BASE, 48, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
03640 { A5BLOCK_FIXED, SPR_ELRAIL_BASE, 48, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
03641 { A5BLOCK_FIXED, SPR_SLOPES_BASE, 74, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
03642 { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" },
03643 { A5BLOCK_FIXED, SPR_CANALS_BASE, 65, CANALS_SPRITE_COUNT, "Canal graphics" },
03644 { A5BLOCK_FIXED, SPR_ONEWAY_BASE, 6, ONEWAY_SPRITE_COUNT, "One way road graphics" },
03645 { A5BLOCK_FIXED, SPR_2CCMAP_BASE, 256, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
03646 { A5BLOCK_FIXED, SPR_TRAMWAY_BASE, 113, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
03647 { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" },
03648 { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
03649 { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" },
03650 { A5BLOCK_FIXED, SPR_TRACKS_FOR_SLOPES_BASE, 12, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
03651 { A5BLOCK_FIXED, SPR_AIRPORTX_BASE, 15, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
03652 { A5BLOCK_FIXED, SPR_ROADSTOP_BASE, 8, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
03653 { A5BLOCK_FIXED, SPR_AQUEDUCT_BASE, 8, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
03654 { A5BLOCK_FIXED, SPR_AUTORAIL_BASE, 55, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
03655 { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
03656 { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
03657 };
03658
03659 if (!check_length(len, 2, "GraphicsNew")) return;
03660 buf++;
03661 uint8 type = grf_load_byte(&buf);
03662 uint16 num = grf_load_extended(&buf);
03663 uint16 offset = HasBit(type, 7) ? grf_load_extended(&buf) : 0;
03664 ClrBit(type, 7);
03665
03666 if ((type == 0x0D) && (num == 10) && _cur_grffile->is_ottdfile) {
03667
03668
03669 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from openttd(d/w).grf.");
03670 LoadNextSprite(SPR_SHORE_BASE + 0, _file_index, _nfo_line++);
03671 LoadNextSprite(SPR_SHORE_BASE + 5, _file_index, _nfo_line++);
03672 LoadNextSprite(SPR_SHORE_BASE + 7, _file_index, _nfo_line++);
03673 LoadNextSprite(SPR_SHORE_BASE + 10, _file_index, _nfo_line++);
03674 LoadNextSprite(SPR_SHORE_BASE + 11, _file_index, _nfo_line++);
03675 LoadNextSprite(SPR_SHORE_BASE + 13, _file_index, _nfo_line++);
03676 LoadNextSprite(SPR_SHORE_BASE + 14, _file_index, _nfo_line++);
03677 LoadNextSprite(SPR_SHORE_BASE + 15, _file_index, _nfo_line++);
03678 LoadNextSprite(SPR_SHORE_BASE + 16, _file_index, _nfo_line++);
03679 LoadNextSprite(SPR_SHORE_BASE + 17, _file_index, _nfo_line++);
03680 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
03681 return;
03682 }
03683
03684
03685 if ((type >= lengthof(action5_types)) || (action5_types[type].block_type == A5BLOCK_INVALID)) {
03686 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
03687 _skip_sprites = num;
03688 return;
03689 }
03690
03691 const Action5Type *action5_type = &action5_types[type];
03692
03693
03694 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
03695 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
03696 offset = 0;
03697 }
03698
03699
03700
03701 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
03702 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);
03703 _skip_sprites = num;
03704 return;
03705 }
03706
03707
03708 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
03709 SpriteID replace = action5_type->sprite_base + offset;
03710
03711
03712 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);
03713
03714 for (; num > 0; num--) {
03715 _nfo_line++;
03716 LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
03717 }
03718
03719 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
03720
03721 _skip_sprites = skip_num;
03722 }
03723
03724
03725 static void SkipAct5(byte *buf, size_t len)
03726 {
03727 if (!check_length(len, 2, "SkipAct5")) return;
03728 buf++;
03729
03730
03731 grf_load_byte(&buf);
03732
03733
03734 _skip_sprites = grf_load_extended(&buf);
03735
03736 grfmsg(3, "SkipAct5: Skipping %d sprites", _skip_sprites);
03737 }
03738
03749 bool GetGlobalVariable(byte param, uint32 *value)
03750 {
03751 switch (param) {
03752 case 0x00:
03753 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
03754 return true;
03755
03756 case 0x01:
03757 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
03758 return true;
03759
03760 case 0x02: {
03761 YearMonthDay ymd;
03762 ConvertDateToYMD(_date, &ymd);
03763 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
03764 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
03765 return true;
03766 }
03767
03768 case 0x03:
03769 *value = _settings_game.game_creation.landscape;
03770 return true;
03771
03772 case 0x06:
03773 *value = _settings_game.vehicle.road_side << 4;
03774 return true;
03775
03776 case 0x09:
03777 *value = _date_fract;
03778 return true;
03779
03780 case 0x0A:
03781 *value = _tick_counter;
03782 return true;
03783
03784 case 0x0B: {
03785 uint major = 2;
03786 uint minor = 6;
03787 uint revision = 1;
03788 uint build = 1382;
03789 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
03790 return true;
03791 }
03792
03793 case 0x0D:
03794 *value = _cur_grfconfig->windows_paletted;
03795 return true;
03796
03797 case 0x0E:
03798 *value = _traininfo_vehicle_pitch;
03799 return true;
03800
03801 case 0x0F:
03802 *value = 0;
03803 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier);
03804 if (_settings_game.vehicle.disable_elrails) {
03805
03806 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier);
03807 } else {
03808 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier);
03809
03810 }
03811 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier);
03812 return true;
03813
03814 case 0x11:
03815 *value = 0;
03816 return true;
03817
03818 case 0x12:
03819 *value = _game_mode;
03820 return true;
03821
03822
03823
03824
03825
03826
03827
03828 case 0x1A:
03829 *value = UINT_MAX;
03830 return true;
03831
03832 case 0x1B:
03833 *value = GB(_display_opt, 0, 6);
03834 return true;
03835
03836 case 0x1D:
03837 *value = 1;
03838 return true;
03839
03840 case 0x1E:
03841 *value = _misc_grf_features;
03842 return true;
03843
03844
03845
03846 case 0x20:
03847 *value = _settings_game.game_creation.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF;
03848 return true;
03849
03850 case 0x21:
03851 *value = _openttd_newgrf_version;
03852 return true;
03853
03854 case 0x22:
03855 *value = _settings_game.difficulty.diff_level;
03856 return true;
03857
03858 case 0x23:
03859 *value = _date;
03860 return true;
03861
03862 case 0x24:
03863 *value = _cur_year;
03864 return true;
03865
03866 default: return false;
03867 }
03868 }
03869
03870 static uint32 GetParamVal(byte param, uint32 *cond_val)
03871 {
03872
03873 uint32 value;
03874 if (GetGlobalVariable(param - 0x80, &value)) return value;
03875
03876
03877 switch (param) {
03878 case 0x84: {
03879 uint32 res = 0;
03880
03881 if (_cur_stage > GLS_INIT) SetBit(res, 0);
03882 if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
03883 if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
03884 return res;
03885 }
03886
03887 case 0x85:
03888 if (cond_val == NULL) {
03889
03890 return 0;
03891 } else {
03892 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
03893 *cond_val %= 0x20;
03894 return param_val;
03895 }
03896
03897 case 0x88:
03898 return 0;
03899
03900
03901
03902 default:
03903
03904 if (param < 0x80) return _cur_grffile->param[param];
03905
03906
03907 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
03908 return UINT_MAX;
03909 }
03910 }
03911
03912
03913 static void CfgApply(byte *buf, size_t len)
03914 {
03915
03916
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
03927 size_t pos = FioGetPos();
03928 uint16 num = FioReadWord();
03929 uint8 type = FioReadByte();
03930 byte *preload_sprite = NULL;
03931
03932
03933 if (type == 0xFF) {
03934 preload_sprite = MallocT<byte>(num);
03935 FioReadBlock(preload_sprite, num);
03936 }
03937
03938
03939 FioSeekTo(pos, SEEK_SET);
03940
03941 if (type != 0xFF) {
03942 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
03943 free(preload_sprite);
03944 return;
03945 }
03946
03947 GRFLocation location(_cur_grfconfig->grfid, _nfo_line + 1);
03948 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
03949 if (it != _grf_line_to_action6_sprite_override.end()) {
03950 free(preload_sprite);
03951 preload_sprite = _grf_line_to_action6_sprite_override[location];
03952 } else {
03953 _grf_line_to_action6_sprite_override[location] = preload_sprite;
03954 }
03955
03956
03957 buf++;
03958
03959 for (;;) {
03960 uint i;
03961 uint param_num;
03962 uint param_size;
03963 uint offset;
03964 bool add_value;
03965
03966
03967 param_num = grf_load_byte(&buf);
03968 if (param_num == 0xFF) break;
03969
03970
03971
03972 param_size = grf_load_byte(&buf);
03973
03974
03975
03976 add_value = HasBit(param_size, 7);
03977 param_size = GB(param_size, 0, 7);
03978
03979
03980 offset = grf_load_extended(&buf);
03981
03982
03983
03984 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur_grffile->param_end) {
03985 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
03986 break;
03987 }
03988
03989 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
03990
03991 bool carry = false;
03992 for (i = 0; i < param_size && offset + i < num; i++) {
03993 uint32 value = GetParamVal(param_num + i / 4, NULL);
03994
03995
03996 if (i == 0) carry = false;
03997
03998 if (add_value) {
03999 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
04000 preload_sprite[offset + i] = GB(new_value, 0, 8);
04001
04002 carry = new_value >= 256;
04003 } else {
04004 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
04005 }
04006 }
04007 }
04008 }
04009
04019 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
04020 {
04021 if (c->error != NULL) {
04022 free(c->error->custom_message);
04023 free(c->error->data);
04024 free(c->error);
04025 }
04026 c->status = GCS_DISABLED;
04027 c->error = CallocT<GRFError>(1);
04028 c->error->data = strdup(_cur_grfconfig->name);
04029 c->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04030 c->error->message = STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC;
04031
04032 ClearTemporaryNewGRFData(GetFileByGRFID(c->grfid));
04033 }
04034
04035
04036
04037 static void SkipIf(byte *buf, size_t len)
04038 {
04039
04040
04041
04042
04043
04044
04045
04046
04047 uint32 cond_val = 0;
04048 uint32 mask = 0;
04049 bool result;
04050
04051 if (!check_length(len, 6, "SkipIf")) return;
04052 buf++;
04053 uint8 param = grf_load_byte(&buf);
04054 uint8 paramsize = grf_load_byte(&buf);
04055 uint8 condtype = grf_load_byte(&buf);
04056
04057 if (condtype < 2) {
04058
04059 paramsize = 1;
04060 }
04061
04062 switch (paramsize) {
04063 case 8: cond_val = grf_load_dword(&buf); mask = grf_load_dword(&buf); break;
04064 case 4: cond_val = grf_load_dword(&buf); mask = 0xFFFFFFFF; break;
04065 case 2: cond_val = grf_load_word(&buf); mask = 0x0000FFFF; break;
04066 case 1: cond_val = grf_load_byte(&buf); mask = 0x000000FF; break;
04067 default: break;
04068 }
04069
04070 if (param < 0x80 && _cur_grffile->param_end <= param) {
04071 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
04072 return;
04073 }
04074
04075 uint32 param_val = GetParamVal(param, &cond_val);
04076
04077 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
04078
04079
04080
04081
04082
04083
04084
04085
04086 if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
04087
04088
04089 GRFConfig *c = GetGRFConfig(cond_val, mask);
04090
04091 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && c->status != GCS_DISABLED && _networking) {
04092 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04093 c = NULL;
04094 }
04095
04096 if (condtype != 10 && c == NULL) {
04097 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
04098 return;
04099 }
04100
04101 switch (condtype) {
04102
04103 case 0x06:
04104 result = c->status == GCS_ACTIVATED;
04105 break;
04106
04107 case 0x07:
04108 result = c->status != GCS_ACTIVATED;
04109 break;
04110
04111 case 0x08:
04112 result = c->status == GCS_INITIALISED;
04113 break;
04114
04115 case 0x09:
04116 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
04117 break;
04118
04119 case 0x0A:
04120
04121 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
04122 break;
04123
04124 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
04125 }
04126 } else {
04127
04128 switch (condtype) {
04129 case 0x00: result = !!(param_val & (1 << cond_val));
04130 break;
04131 case 0x01: result = !(param_val & (1 << cond_val));
04132 break;
04133 case 0x02: result = (param_val & mask) == cond_val;
04134 break;
04135 case 0x03: result = (param_val & mask) != cond_val;
04136 break;
04137 case 0x04: result = (param_val & mask) < cond_val;
04138 break;
04139 case 0x05: result = (param_val & mask) > cond_val;
04140 break;
04141 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
04142 break;
04143 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
04144 break;
04145 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
04146 break;
04147 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
04148 break;
04149
04150 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
04151 }
04152 }
04153
04154 if (!result) {
04155 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
04156 return;
04157 }
04158
04159 uint8 numsprites = grf_load_byte(&buf);
04160
04161
04162
04163
04164
04165 GRFLabel *choice = NULL;
04166 for (GRFLabel *label = _cur_grffile->label; label != NULL; label = label->next) {
04167 if (label->label != numsprites) continue;
04168
04169
04170 if (choice == NULL) choice = label;
04171
04172 if (label->nfo_line > _nfo_line) {
04173 choice = label;
04174 break;
04175 }
04176 }
04177
04178 if (choice != NULL) {
04179 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
04180 FioSeekTo(choice->pos, SEEK_SET);
04181 _nfo_line = choice->nfo_line;
04182 return;
04183 }
04184
04185 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
04186 _skip_sprites = numsprites;
04187 if (_skip_sprites == 0) {
04188
04189
04190
04191 _skip_sprites = -1;
04192
04193
04194 if (_cur_grfconfig->status != GCS_ACTIVATED) {
04195 _cur_grfconfig->status = GCS_DISABLED;
04196 ClearTemporaryNewGRFData(_cur_grffile);
04197 }
04198 }
04199 }
04200
04201
04202
04203 static void ScanInfo(byte *buf, size_t len)
04204 {
04205 if (!check_length(len, 8, "Info")) return;
04206 buf++;
04207 grf_load_byte(&buf);
04208 uint32 grfid = grf_load_dword(&buf);
04209
04210 _cur_grfconfig->grfid = grfid;
04211
04212
04213 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
04214
04215 len -= 6;
04216 const char *name = grf_load_string(&buf, len);
04217 _cur_grfconfig->name = TranslateTTDPatchCodes(grfid, name);
04218
04219 len -= strlen(name) + 1;
04220 if (len > 0) {
04221 const char *info = grf_load_string(&buf, len);
04222 _cur_grfconfig->info = TranslateTTDPatchCodes(grfid, info);
04223 }
04224
04225
04226 _skip_sprites = -1;
04227 }
04228
04229
04230 static void GRFInfo(byte *buf, size_t len)
04231 {
04232
04233
04234
04235
04236
04237
04238
04239 if (!check_length(len, 8, "GRFInfo")) return;
04240 buf++;
04241 uint8 version = grf_load_byte(&buf);
04242 uint32 grfid = grf_load_dword(&buf);
04243 const char *name = grf_load_string(&buf, len - 6);
04244
04245 if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
04246 _cur_grfconfig->status = GCS_DISABLED;
04247 _cur_grfconfig->error = CallocT<GRFError>(1);
04248 _cur_grfconfig->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
04249 _cur_grfconfig->error->message = STR_NEWGRF_ERROR_MULTIPLE_ACTION_8;
04250
04251 _skip_sprites = -1;
04252 return;
04253 }
04254
04255 _cur_grffile->grfid = grfid;
04256 _cur_grffile->grf_version = version;
04257 _cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
04258
04259
04260 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, _cur_grfconfig->windows_paletted ? "Windows" : "DOS");
04261 }
04262
04263
04264 static void SpriteReplace(byte *buf, size_t len)
04265 {
04266
04267
04268
04269
04270
04271
04272
04273
04274 buf++;
04275 uint8 num_sets = grf_load_byte(&buf);
04276
04277 for (uint i = 0; i < num_sets; i++) {
04278 uint8 num_sprites = grf_load_byte(&buf);
04279 uint16 first_sprite = grf_load_word(&buf);
04280
04281 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
04282 i, num_sprites, first_sprite
04283 );
04284
04285 for (uint j = 0; j < num_sprites; j++) {
04286 int load_index = first_sprite + j;
04287 _nfo_line++;
04288 LoadNextSprite(load_index, _file_index, _nfo_line);
04289
04290
04291
04292 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
04293 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
04294 }
04295 }
04296 }
04297 }
04298
04299
04300 static void SkipActA(byte *buf, size_t len)
04301 {
04302 buf++;
04303 uint8 num_sets = grf_load_byte(&buf);
04304
04305 for (uint i = 0; i < num_sets; i++) {
04306
04307 _skip_sprites += grf_load_byte(&buf);
04308
04309 grf_load_word(&buf);
04310 }
04311
04312 grfmsg(3, "SkipActA: Skipping %d sprites", _skip_sprites);
04313 }
04314
04315
04316 static void GRFLoadError(byte *buf, size_t len)
04317 {
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333 static const StringID msgstr[] = {
04334 STR_NEWGRF_ERROR_VERSION_NUMBER,
04335 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
04336 STR_NEWGRF_ERROR_UNSET_SWITCH,
04337 STR_NEWGRF_ERROR_INVALID_PARAMETER,
04338 STR_NEWGRF_ERROR_LOAD_BEFORE,
04339 STR_NEWGRF_ERROR_LOAD_AFTER,
04340 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
04341 };
04342
04343 static const StringID sevstr[] = {
04344 STR_NEWGRF_ERROR_MSG_INFO,
04345 STR_NEWGRF_ERROR_MSG_WARNING,
04346 STR_NEWGRF_ERROR_MSG_ERROR,
04347 STR_NEWGRF_ERROR_MSG_FATAL
04348 };
04349
04350 if (!check_length(len, 6, "GRFLoadError")) return;
04351
04352
04353 if (_cur_grfconfig->error != NULL) return;
04354
04355 buf++;
04356 byte severity = grf_load_byte(&buf);
04357 byte lang = grf_load_byte(&buf);
04358 byte message_id = grf_load_byte(&buf);
04359 len -= 4;
04360
04361
04362 if (!CheckGrfLangID(lang, _cur_grffile->grf_version)) return;
04363
04364
04365
04366 if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
04367 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
04368 return;
04369 }
04370 ClrBit(severity, 7);
04371
04372 if (severity >= lengthof(sevstr)) {
04373 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
04374 severity = 2;
04375 } else if (severity == 3) {
04376
04377
04378 _cur_grfconfig->status = GCS_DISABLED;
04379 ClearTemporaryNewGRFData(_cur_grffile);
04380 _skip_sprites = -1;
04381 }
04382
04383 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
04384 grfmsg(7, "GRFLoadError: Invalid message id.");
04385 return;
04386 }
04387
04388 if (len <= 1) {
04389 grfmsg(7, "GRFLoadError: No message data supplied.");
04390 return;
04391 }
04392
04393 GRFError *error = CallocT<GRFError>(1);
04394
04395 error->severity = sevstr[severity];
04396
04397 if (message_id == 0xFF) {
04398
04399 const char *message = grf_load_string(&buf, len);
04400 len -= (strlen(message) + 1);
04401
04402 error->custom_message = TranslateTTDPatchCodes(_cur_grffile->grfid, message);
04403 } else {
04404 error->message = msgstr[message_id];
04405 }
04406
04407 if (len > 0) {
04408 const char *data = grf_load_string(&buf, len);
04409 len -= (strlen(data) + 1);
04410
04411 error->data = TranslateTTDPatchCodes(_cur_grffile->grfid, data);
04412 }
04413
04414
04415 uint i = 0;
04416 for (; i < 2 && len > 0; i++) {
04417 uint param_number = grf_load_byte(&buf);
04418 error->param_value[i] = (param_number < _cur_grffile->param_end ? _cur_grffile->param[param_number] : 0);
04419 len--;
04420 }
04421 error->num_params = i;
04422
04423 _cur_grfconfig->error = error;
04424 }
04425
04426
04427 static void GRFComment(byte *buf, size_t len)
04428 {
04429
04430
04431
04432
04433 if (len == 1) return;
04434
04435 size_t text_len = len - 1;
04436 const char *text = (const char*)(buf + 1);
04437 grfmsg(2, "GRFComment: %.*s", (int)text_len, text);
04438 }
04439
04440
04441 static void SafeParamSet(byte *buf, size_t len)
04442 {
04443 if (!check_length(len, 5, "SafeParamSet")) return;
04444 buf++;
04445 uint8 target = grf_load_byte(&buf);
04446
04447
04448 if (target < 0x80) return;
04449
04450
04451
04452
04453
04454
04455 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04456
04457
04458 _skip_sprites = -1;
04459 }
04460
04461
04462 static uint32 GetPatchVariable(uint8 param)
04463 {
04464 switch (param) {
04465
04466 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
04467
04468
04469 case 0x0E: return _settings_game.vehicle.freight_trains;
04470
04471
04472 case 0x0F: return 0;
04473
04474
04475
04476
04477 case 0x10:
04478 switch (_settings_game.vehicle.plane_speed) {
04479 default:
04480 case 4: return 1;
04481 case 3: return 2;
04482 case 2: return 2;
04483 case 1: return 4;
04484 }
04485
04486
04487
04488 case 0x11: return SPR_2CCMAP_BASE;
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501 case 0x13: {
04502 byte map_bits = 0;
04503 byte log_X = MapLogX() - 6;
04504 byte log_Y = MapLogY() - 6;
04505 byte max_edge = max(log_X, log_Y);
04506
04507 if (log_X == log_Y) {
04508 SetBit(map_bits ,0);
04509 } else {
04510 if (max_edge == log_Y) SetBit(map_bits, 1);
04511 }
04512
04513 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
04514 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
04515 }
04516
04517 default:
04518 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
04519 return 0;
04520 }
04521 }
04522
04523
04524 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
04525 {
04526 uint start = 0;
04527 uint size = 0;
04528
04529 if (op == 6) {
04530
04531 return grm[_cur_grffile->param[target]];
04532 }
04533
04534
04535 if (op == 2 || op == 3) start = _cur_grffile->param[target];
04536
04537 for (uint i = start; i < num_ids; i++) {
04538 if (grm[i] == 0) {
04539 size++;
04540 } else {
04541 if (op == 2 || op == 3) break;
04542 start = i + 1;
04543 size = 0;
04544 }
04545
04546 if (size == count) break;
04547 }
04548
04549 if (size == count) {
04550
04551 if (op == 0 || op == 3) {
04552 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
04553 for (uint i = 0; i < count; i++) grm[start + i] = _cur_grffile->grfid;
04554 }
04555 return start;
04556 }
04557
04558
04559 if (op != 4 && op != 5) {
04560
04561 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
04562 _cur_grfconfig->status = GCS_DISABLED;
04563 ClearTemporaryNewGRFData(_cur_grffile);
04564 _skip_sprites = -1;
04565 return UINT_MAX;
04566 }
04567
04568 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
04569 return UINT_MAX;
04570 }
04571
04572
04573
04574 static void ParamSet(byte *buf, size_t len)
04575 {
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597
04598 if (!check_length(len, 5, "ParamSet")) return;
04599 buf++;
04600 uint8 target = grf_load_byte(&buf);
04601 uint8 oper = grf_load_byte(&buf);
04602 uint32 src1 = grf_load_byte(&buf);
04603 uint32 src2 = grf_load_byte(&buf);
04604
04605 uint32 data = 0;
04606 if (len >= 8) data = grf_load_dword(&buf);
04607
04608
04609
04610
04611
04612
04613
04614 if (HasBit(oper, 7)) {
04615 if (target < 0x80 && target < _cur_grffile->param_end) {
04616 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
04617 return;
04618 }
04619
04620 oper = GB(oper, 0, 7);
04621 }
04622
04623 if (src2 == 0xFE) {
04624 if (GB(data, 0, 8) == 0xFF) {
04625 if (data == 0x0000FFFF) {
04626
04627 src1 = GetPatchVariable(src1);
04628 } else {
04629
04630 uint8 op = src1;
04631 uint8 feature = GB(data, 8, 8);
04632 uint16 count = GB(data, 16, 16);
04633
04634 if (_cur_stage == GLS_RESERVE) {
04635 if (feature == 0x08) {
04636
04637 if (op == 0) {
04638
04639 if (_cur_spriteid + count >= 16384) {
04640 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
04641 _cur_grfconfig->status = GCS_DISABLED;
04642 ClearTemporaryNewGRFData(_cur_grffile);
04643 _skip_sprites = -1;
04644 return;
04645 }
04646
04647
04648 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur_spriteid);
04649 _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)] = _cur_spriteid;
04650 _cur_spriteid += count;
04651 }
04652 }
04653
04654 src1 = 0;
04655 } else if (_cur_stage == GLS_ACTIVATION) {
04656 switch (feature) {
04657 case 0x00:
04658 case 0x01:
04659 case 0x02:
04660 case 0x03:
04661 if (!_settings_game.vehicle.dynamic_engines) {
04662 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
04663 if (_skip_sprites == -1) return;
04664 } else {
04665
04666 switch (op) {
04667 case 2:
04668 case 3:
04669 src1 = _cur_grffile->param[target];
04670 break;
04671
04672 default:
04673 src1 = 0;
04674 break;
04675 }
04676 }
04677 break;
04678
04679 case 0x08:
04680 switch (op) {
04681 case 0:
04682
04683 src1 = _grm_sprites[GRFLocation(_cur_grffile->grfid, _nfo_line)];
04684 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
04685 break;
04686
04687 case 1:
04688 src1 = _cur_spriteid;
04689 break;
04690
04691 default:
04692 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
04693 return;
04694 }
04695 break;
04696
04697 case 0x0B:
04698
04699 src1 = PerformGRM(_grm_cargos, NUM_CARGO * 2, count, op, target, "cargos");
04700 if (_skip_sprites == -1) return;
04701 break;
04702
04703 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
04704 }
04705 } else {
04706
04707 src1 = 0;
04708 }
04709 }
04710 } else {
04711
04712 const GRFFile *file = GetFileByGRFID(data);
04713 GRFConfig *c = GetGRFConfig(data);
04714 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur_grfconfig->flags, GCF_STATIC) && _networking) {
04715
04716 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
04717 src1 = 0;
04718 } else if (file == NULL || src1 >= file->param_end || (c != NULL && c->status == GCS_DISABLED)) {
04719 src1 = 0;
04720 } else {
04721 src1 = file->param[src1];
04722 }
04723 }
04724 } else {
04725
04726
04727
04728
04729
04730 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
04731 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
04732 }
04733
04734
04735
04736
04737
04738
04739
04740 uint32 res;
04741 switch (oper) {
04742 case 0x00:
04743 res = src1;
04744 break;
04745
04746 case 0x01:
04747 res = src1 + src2;
04748 break;
04749
04750 case 0x02:
04751 res = src1 - src2;
04752 break;
04753
04754 case 0x03:
04755 res = src1 * src2;
04756 break;
04757
04758 case 0x04:
04759 res = (int32)src1 * (int32)src2;
04760 break;
04761
04762 case 0x05:
04763 if ((int32)src2 < 0) {
04764 res = src1 >> -(int32)src2;
04765 } else {
04766 res = src1 << src2;
04767 }
04768 break;
04769
04770 case 0x06:
04771 if ((int32)src2 < 0) {
04772 res = (int32)src1 >> -(int32)src2;
04773 } else {
04774 res = (int32)src1 << src2;
04775 }
04776 break;
04777
04778 case 0x07:
04779 res = src1 & src2;
04780 break;
04781
04782 case 0x08:
04783 res = src1 | src2;
04784 break;
04785
04786 case 0x09:
04787 if (src2 == 0) {
04788 res = src1;
04789 } else {
04790 res = src1 / src2;
04791 }
04792 break;
04793
04794 case 0x0A:
04795 if (src2 == 0) {
04796 res = src1;
04797 } else {
04798 res = (int32)src1 / (int32)src2;
04799 }
04800 break;
04801
04802 case 0x0B:
04803 if (src2 == 0) {
04804 res = src1;
04805 } else {
04806 res = src1 % src2;
04807 }
04808 break;
04809
04810 case 0x0C:
04811 if (src2 == 0) {
04812 res = src1;
04813 } else {
04814 res = (int32)src1 % (int32)src2;
04815 }
04816 break;
04817
04818 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
04819 }
04820
04821 switch (target) {
04822 case 0x8E:
04823 _traininfo_vehicle_pitch = res;
04824 break;
04825
04826 case 0x8F: {
04827 extern RailtypeInfo _railtypes[RAILTYPE_END];
04828 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
04829 if (_settings_game.vehicle.disable_elrails) {
04830 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
04831 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
04832 } else {
04833 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
04834 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
04835 }
04836 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
04837 break;
04838 }
04839
04840
04841 case 0x93:
04842 case 0x94:
04843 case 0x95:
04844 case 0x96:
04845 case 0x97:
04846 case 0x99:
04847 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
04848 break;
04849
04850 case 0x9E:
04851 _misc_grf_features = res;
04852
04853 _traininfo_vehicle_width = HasGrfMiscBit(GMB_TRAIN_WIDTH_32_PIXELS) ? 32 : 29;
04854 break;
04855
04856 case 0x9F:
04857 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
04858 break;
04859
04860 default:
04861 if (target < 0x80) {
04862 _cur_grffile->param[target] = res;
04863 if (target + 1U > _cur_grffile->param_end) _cur_grffile->param_end = target + 1;
04864 } else {
04865 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
04866 }
04867 break;
04868 }
04869 }
04870
04871
04872 static void SafeGRFInhibit(byte *buf, size_t len)
04873 {
04874
04875
04876
04877
04878
04879 if (!check_length(len, 2, "GRFInhibit")) return;
04880 buf++;
04881 uint8 num = grf_load_byte(&buf);
04882 if (!check_length(len, 2 + 4 * num, "GRFInhibit")) return;
04883
04884 for (uint i = 0; i < num; i++) {
04885 uint32 grfid = grf_load_dword(&buf);
04886
04887
04888 if (grfid != _cur_grfconfig->grfid) {
04889 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
04890
04891
04892 _skip_sprites = -1;
04893
04894 return;
04895 }
04896 }
04897 }
04898
04899
04900 static void GRFInhibit(byte *buf, size_t len)
04901 {
04902
04903
04904
04905
04906
04907 if (!check_length(len, 2, "GRFInhibit")) return;
04908 buf++;
04909 uint8 num = grf_load_byte(&buf);
04910 if (!check_length(len, 2 + 4 * num, "GRFInhibit")) return;
04911
04912 for (uint i = 0; i < num; i++) {
04913 uint32 grfid = grf_load_dword(&buf);
04914 GRFConfig *file = GetGRFConfig(grfid);
04915
04916
04917 if (file != NULL && file != _cur_grfconfig) {
04918 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
04919 file->status = GCS_DISABLED;
04920 }
04921 }
04922 }
04923
04924
04925 static void FeatureTownName(byte *buf, size_t len)
04926 {
04927
04928
04929
04930
04931
04932
04933
04934 if (!check_length(len, 1, "FeatureTownName: definition ID")) return;
04935 buf++; len--;
04936
04937 uint32 grfid = _cur_grffile->grfid;
04938
04939 GRFTownName *townname = AddGRFTownName(grfid);
04940
04941 byte id = grf_load_byte(&buf);
04942 len--;
04943 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
04944
04945 if (HasBit(id, 7)) {
04946
04947 ClrBit(id, 7);
04948 bool new_scheme = _cur_grffile->grf_version >= 7;
04949
04950 if (!check_length(len, 1, "FeatureTownName: lang_id")) return;
04951 byte lang = grf_load_byte(&buf);
04952 len--;
04953
04954 byte nb_gen = townname->nb_gen;
04955 do {
04956 ClrBit(lang, 7);
04957
04958 if (!check_length(len, 1, "FeatureTownName: style name")) return;
04959 const char *name = grf_load_string(&buf, len);
04960 len -= strlen(name) + 1;
04961
04962 char *lang_name = TranslateTTDPatchCodes(grfid, name);
04963 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
04964 free(lang_name);
04965
04966 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, name, STR_UNDEFINED);
04967
04968 if (!check_length(len, 1, "FeatureTownName: lang_id")) return;
04969 lang = grf_load_byte(&buf);
04970 len--;
04971 } while (lang != 0);
04972 townname->id[nb_gen] = id;
04973 townname->nb_gen++;
04974 }
04975
04976 if (!check_length(len, 1, "FeatureTownName: number of parts")) return;
04977 byte nb = grf_load_byte(&buf);
04978 len--;
04979 grfmsg(6, "FeatureTownName: %u parts", nb);
04980
04981 townname->nbparts[id] = nb;
04982 townname->partlist[id] = CallocT<NamePartList>(nb);
04983
04984 for (int i = 0; i < nb; i++) {
04985 if (!check_length(len, 3, "FeatureTownName: parts header")) return;
04986 byte nbtext = grf_load_byte(&buf);
04987 townname->partlist[id][i].bitstart = grf_load_byte(&buf);
04988 townname->partlist[id][i].bitcount = grf_load_byte(&buf);
04989 townname->partlist[id][i].maxprob = 0;
04990 townname->partlist[id][i].partcount = nbtext;
04991 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
04992 len -= 3;
04993 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);
04994
04995 for (int j = 0; j < nbtext; j++) {
04996 if (!check_length(len, 2, "FeatureTownName: part")) return;
04997 byte prob = grf_load_byte(&buf);
04998 len--;
04999
05000 if (HasBit(prob, 7)) {
05001 byte ref_id = grf_load_byte(&buf);
05002 len--;
05003
05004 if (townname->nbparts[ref_id] == 0) {
05005 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
05006 DelGRFTownName(grfid);
05007 _cur_grfconfig->status = GCS_DISABLED;
05008 ClearTemporaryNewGRFData(_cur_grffile);
05009 _skip_sprites = -1;
05010 return;
05011 }
05012
05013 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
05014 townname->partlist[id][i].parts[j].data.id = ref_id;
05015 } else {
05016 const char *text = grf_load_string(&buf, len);
05017 len -= strlen(text) + 1;
05018 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, text);
05019 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
05020 }
05021 townname->partlist[id][i].parts[j].prob = prob;
05022 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
05023 }
05024 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
05025 }
05026 }
05027
05028
05029 static void DefineGotoLabel(byte *buf, size_t len)
05030 {
05031
05032
05033
05034
05035
05036 if (!check_length(len, 1, "DefineGotoLabel")) return;
05037 buf++; len--;
05038
05039 GRFLabel *label = MallocT<GRFLabel>(1);
05040 label->label = grf_load_byte(&buf);
05041 label->nfo_line = _nfo_line;
05042 label->pos = FioGetPos();
05043 label->next = NULL;
05044
05045
05046 if (_cur_grffile->label == NULL) {
05047 _cur_grffile->label = label;
05048 } else {
05049
05050 GRFLabel *l;
05051 for (l = _cur_grffile->label; l->next != NULL; l = l->next) {}
05052 l->next = label;
05053 }
05054
05055 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
05056 }
05057
05058
05059 static void GRFSound(byte *buf, size_t len)
05060 {
05061
05062
05063
05064
05065 if (!check_length(len, 1, "GRFSound")) return;
05066 buf++;
05067 uint16 num = grf_load_word(&buf);
05068
05069 _grf_data_blocks = num;
05070 _grf_data_type = GDT_SOUND;
05071
05072 if (_cur_grffile->sound_offset == 0) _cur_grffile->sound_offset = GetNumSounds();
05073 }
05074
05075
05076 static void SkipAct11(byte *buf, size_t len)
05077 {
05078
05079
05080
05081
05082 if (!check_length(len, 1, "SkipAct11")) return;
05083 buf++;
05084 _skip_sprites = grf_load_word(&buf);
05085
05086 grfmsg(3, "SkipAct11: Skipping %d sprites", _skip_sprites);
05087 }
05088
05089 static void ImportGRFSound(byte *buf, int len)
05090 {
05091 const GRFFile *file;
05092 FileEntry *se = AllocateFileEntry();
05093 uint32 grfid = grf_load_dword(&buf);
05094 uint16 sound = grf_load_word(&buf);
05095
05096 file = GetFileByGRFID(grfid);
05097 if (file == NULL || file->sound_offset == 0) {
05098 grfmsg(1, "ImportGRFSound: Source file not available");
05099 return;
05100 }
05101
05102 if (file->sound_offset + sound >= GetNumSounds()) {
05103 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound);
05104 return;
05105 }
05106
05107 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound, file->sound_offset + sound, grfid);
05108
05109 *se = *GetSound(file->sound_offset + sound);
05110
05111
05112 se->volume = 128;
05113 se->priority = 0;
05114 }
05115
05116
05117 static void GRFImportBlock(byte *buf, int len)
05118 {
05119 if (_grf_data_blocks == 0) {
05120 grfmsg(2, "GRFImportBlock: Unexpected import block, skipping");
05121 return;
05122 }
05123
05124 buf++;
05125
05126 _grf_data_blocks--;
05127
05128
05129
05130 if (grf_load_byte(&buf) != _grf_data_type) {
05131 grfmsg(1, "GRFImportBlock: Import type mismatch");
05132 }
05133
05134 switch (_grf_data_type) {
05135 case GDT_SOUND: ImportGRFSound(buf, len - 1); break;
05136 default: NOT_REACHED(); break;
05137 }
05138 }
05139
05140 static void LoadGRFSound(byte *buf, int len)
05141 {
05142 byte *buf_start = buf;
05143
05144
05145
05146 FileEntry *se = AllocateFileEntry();
05147
05148 if (grf_load_dword(&buf) != BSWAP32('RIFF')) {
05149 grfmsg(1, "LoadGRFSound: Missing RIFF header");
05150 return;
05151 }
05152
05153
05154 grf_load_dword(&buf);
05155
05156 if (grf_load_dword(&buf) != BSWAP32('WAVE')) {
05157 grfmsg(1, "LoadGRFSound: Invalid RIFF type");
05158 return;
05159 }
05160
05161 for (;;) {
05162 uint32 tag = grf_load_dword(&buf);
05163 uint32 size = grf_load_dword(&buf);
05164
05165 switch (tag) {
05166 case ' tmf':
05167
05168 if (grf_load_word(&buf) != 1) {
05169 grfmsg(1, "LoadGRFSound: Invalid audio format");
05170 return;
05171 }
05172 se->channels = grf_load_word(&buf);
05173 se->rate = grf_load_dword(&buf);
05174 grf_load_dword(&buf);
05175 grf_load_word(&buf);
05176 se->bits_per_sample = grf_load_word(&buf);
05177
05178
05179 for (; size > 16; size--) grf_load_byte(&buf);
05180 break;
05181
05182 case 'atad':
05183 se->file_size = size;
05184 se->file_offset = FioGetPos() - (len - (buf - buf_start)) + 1;
05185 se->file_slot = _file_index;
05186
05187
05188 se->volume = 0x80;
05189 se->priority = 0;
05190
05191 grfmsg(2, "LoadGRFSound: channels %u, sample rate %u, bits per sample %u, length %u", se->channels, se->rate, se->bits_per_sample, size);
05192 return;
05193
05194 default:
05195 se->file_size = 0;
05196 return;
05197 }
05198 }
05199 }
05200
05201
05202 static void LoadFontGlyph(byte *buf, size_t len)
05203 {
05204
05205
05206
05207
05208
05209
05210
05211 buf++; len--;
05212 if (!check_length(len, 1, "LoadFontGlyph")) return;
05213
05214 uint8 num_def = grf_load_byte(&buf);
05215
05216 if (!check_length(len, 1 + num_def * 4, "LoadFontGlyph")) return;
05217
05218 for (uint i = 0; i < num_def; i++) {
05219 FontSize size = (FontSize)grf_load_byte(&buf);
05220 uint8 num_char = grf_load_byte(&buf);
05221 uint16 base_char = grf_load_word(&buf);
05222
05223 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
05224
05225 for (uint c = 0; c < num_char; c++) {
05226 SetUnicodeGlyph(size, base_char + c, _cur_spriteid);
05227 _nfo_line++;
05228 LoadNextSprite(_cur_spriteid++, _file_index, _nfo_line);
05229 }
05230 }
05231 }
05232
05233
05234 static void SkipAct12(byte *buf, size_t len)
05235 {
05236
05237
05238
05239
05240
05241
05242
05243 buf++; len--;
05244 if (!check_length(len, 1, "SkipAct12")) return;
05245 uint8 num_def = grf_load_byte(&buf);
05246
05247 if (!check_length(len, 1 + num_def * 4, "SkipAct12")) return;
05248
05249 for (uint i = 0; i < num_def; i++) {
05250
05251 grf_load_byte(&buf);
05252
05253
05254 _skip_sprites += grf_load_byte(&buf);
05255
05256
05257 grf_load_word(&buf);
05258 }
05259
05260 grfmsg(3, "SkipAct12: Skipping %d sprites", _skip_sprites);
05261 }
05262
05263
05264 static void TranslateGRFStrings(byte *buf, size_t len)
05265 {
05266
05267
05268
05269
05270
05271
05272
05273 buf++; len--;
05274 if (!check_length(len, 7, "TranslateGRFString")) return;
05275
05276 uint32 grfid = grf_load_dword(&buf);
05277 const GRFConfig *c = GetGRFConfig(grfid);
05278 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
05279 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
05280 return;
05281 }
05282
05283 if (c->status == GCS_INITIALISED) {
05284
05285
05286 GRFError *error = CallocT<GRFError>(1);
05287
05288 char tmp[256];
05289 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
05290 error->data = strdup(tmp);
05291
05292 error->message = STR_NEWGRF_ERROR_LOAD_AFTER;
05293 error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
05294
05295 if (_cur_grfconfig->error != NULL) free(_cur_grfconfig->error);
05296 _cur_grfconfig->error = error;
05297
05298 _cur_grfconfig->status = GCS_DISABLED;
05299 ClearTemporaryNewGRFData(_cur_grffile);
05300 _skip_sprites = -1;
05301 return;
05302 }
05303
05304 byte num_strings = grf_load_byte(&buf);
05305 uint16 first_id = grf_load_word(&buf);
05306
05307 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
05308 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
05309 return;
05310 }
05311
05312 len -= 7;
05313
05314 for (uint i = 0; i < num_strings && len > 0; i++) {
05315 const char *string = grf_load_string(&buf, len);
05316 size_t string_length = strlen(string) + 1;
05317
05318 len -= (int)string_length;
05319
05320 if (string_length == 1) {
05321 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
05322 continue;
05323 }
05324
05325
05326
05327
05328
05329
05330 AddGRFString(grfid, first_id + i, 0x7F, true, string, STR_UNDEFINED);
05331 }
05332 }
05333
05334
05335 static void GRFDataBlock(byte *buf, int len)
05336 {
05337 if (_grf_data_blocks == 0) {
05338 grfmsg(2, "GRFDataBlock: unexpected data block, skipping");
05339 return;
05340 }
05341
05342 buf++;
05343 uint8 name_len = grf_load_byte(&buf);
05344 const char *name = (const char *)buf;
05345 buf += name_len + 1;
05346
05347 grfmsg(2, "GRFDataBlock: block name '%s'...", name);
05348
05349 _grf_data_blocks--;
05350
05351 switch (_grf_data_type) {
05352 case GDT_SOUND: LoadGRFSound(buf, len - name_len - 2); break;
05353 default: NOT_REACHED(); break;
05354 }
05355 }
05356
05357
05358
05359 static void GRFUnsafe(byte *buf, size_t len)
05360 {
05361 SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
05362
05363
05364 _skip_sprites = -1;
05365 }
05366
05367
05368 static void InitializeGRFSpecial()
05369 {
05370 _ttdpatch_flags[0] = ((_settings_game.station.always_small_airport ? 1 : 0) << 0x0C)
05371 | (1 << 0x0D)
05372 | (1 << 0x0E)
05373 | ((_settings_game.construction.longbridges ? 1 : 0) << 0x0F)
05374 | (0 << 0x10)
05375 | (1 << 0x12)
05376 | (1 << 0x13)
05377 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16)
05378 | (1 << 0x1B)
05379 | (1 << 0x1D)
05380 | (1 << 0x1E);
05381
05382 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07)
05383 | ((_settings_game.vehicle.mammoth_trains ? 1 : 0) << 0x08)
05384 | (1 << 0x09)
05385 | (0 << 0x0B)
05386 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C)
05387 | (1 << 0x12)
05388 | (1 << 0x13)
05389 | (1 << 0x14)
05390 | (1 << 0x16)
05391 | (1 << 0x17)
05392 | (1 << 0x18)
05393 | (1 << 0x19)
05394 | (1 << 0x1A)
05395 | ((_settings_game.construction.signal_side ? 1 : 0) << 0x1B)
05396 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C);
05397
05398 _ttdpatch_flags[2] = (1 << 0x01)
05399 | (1 << 0x03)
05400 | (0 << 0x0B)
05401 | (0 << 0x0C)
05402 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D)
05403 | (1 << 0x0E)
05404 | (1 << 0x0F)
05405 | (0 << 0x10)
05406 | (0 << 0x11)
05407 | (1 << 0x12)
05408 | (1 << 0x13)
05409 | (1 << 0x14)
05410 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15)
05411 | (1 << 0x16)
05412 | (1 << 0x17)
05413 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18)
05414 | (1 << 0x19)
05415 | (1 << 0x1A)
05416 | (1 << 0x1B)
05417 | (1 << 0x1C)
05418 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D)
05419 | (1 << 0x1E)
05420 | (0 << 0x1F);
05421
05422 _ttdpatch_flags[3] = (0 << 0x00)
05423 | (1 << 0x01)
05424 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02)
05425 | (1 << 0x03)
05426 | (0 << 0x04)
05427 | (1 << 0x05)
05428 | (1 << 0x06)
05429 | (1 << 0x07)
05430 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08)
05431 | (0 << 0x09)
05432 | (0 << 0x0A)
05433 | (1 << 0x0B)
05434 | (1 << 0x0C)
05435 | (1 << 0x0D)
05436 | ((_settings_game.station.nonuniform_stations ? 1 : 0) << 0x0E)
05437 | (1 << 0x0F)
05438 | (1 << 0x10)
05439 | (1 << 0x11)
05440 | (1 << 0x12)
05441 | (0 << 0x13)
05442 | (1 << 0x14)
05443 | (0 << 0x15)
05444 | (1 << 0x16)
05445 | (1 << 0x17)
05446 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18)
05447 | (1 << 0x1E)
05448 | (1 << 0x1F);
05449 }
05450
05451 static void ResetCustomStations()
05452 {
05453 for (GRFFile *file = _first_grffile; file != NULL; file = file->next) {
05454 if (file->stations == NULL) continue;
05455 for (uint i = 0; i < MAX_STATIONS; i++) {
05456 if (file->stations[i] == NULL) continue;
05457 StationSpec *statspec = file->stations[i];
05458
05459
05460 if (!statspec->copied_renderdata) {
05461 for (uint t = 0; t < statspec->tiles; t++) {
05462 free((void*)statspec->renderdata[t].seq);
05463 }
05464 free(statspec->renderdata);
05465 }
05466
05467
05468 if (!statspec->copied_layouts) {
05469 for (uint l = 0; l < statspec->lengths; l++) {
05470 for (uint p = 0; p < statspec->platforms[l]; p++) {
05471 free(statspec->layouts[l][p]);
05472 }
05473 free(statspec->layouts[l]);
05474 }
05475 free(statspec->layouts);
05476 free(statspec->platforms);
05477 }
05478
05479
05480 free(statspec);
05481 }
05482
05483
05484 free(file->stations);
05485 file->stations = NULL;
05486 }
05487 }
05488
05489 static void ResetCustomHouses()
05490 {
05491 GRFFile *file;
05492 uint i;
05493
05494 for (file = _first_grffile; file != NULL; file = file->next) {
05495 if (file->housespec == NULL) continue;
05496 for (i = 0; i < HOUSE_MAX; i++) {
05497 free(file->housespec[i]);
05498 }
05499
05500 free(file->housespec);
05501 file->housespec = NULL;
05502 }
05503 }
05504
05505 static void ResetCustomIndustries()
05506 {
05507 GRFFile *file;
05508
05509 for (file = _first_grffile; file != NULL; file = file->next) {
05510 uint i;
05511
05512
05513 if (file->industryspec != NULL) {
05514
05515 for (i = 0; i < NUM_INDUSTRYTYPES; i++) {
05516 IndustrySpec *ind = file->industryspec[i];
05517
05518 if (ind != NULL) {
05519
05520 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
05521 free((void*)ind->random_sounds);
05522 }
05523
05524
05525 if (HasBit(ind->cleanup_flag, CLEAN_TILELSAYOUT) && ind->table != NULL) {
05526 for (int j = 0; j < ind->num_table; j++) {
05527
05528 if (ind->table[j] != NULL) {
05529 free((IndustryTileTable*)ind->table[j]);
05530 }
05531 }
05532
05533 free((IndustryTileTable**)ind->table);
05534 ind->table = NULL;
05535 }
05536
05537 free(ind);
05538 ind = NULL;
05539 }
05540 }
05541
05542 free(file->industryspec);
05543 file->industryspec = NULL;
05544 }
05545
05546 if (file->indtspec != NULL) {
05547 for (i = 0; i < NUM_INDUSTRYTILES; i++) {
05548 if (file->indtspec[i] != NULL) {
05549 free(file->indtspec[i]);
05550 file->indtspec[i] = NULL;
05551 }
05552 }
05553
05554 free(file->indtspec);
05555 file->indtspec = NULL;
05556 }
05557 }
05558 }
05559
05560 static void ResetNewGRF()
05561 {
05562 GRFFile *next;
05563
05564 for (GRFFile *f = _first_grffile; f != NULL; f = next) {
05565 next = f->next;
05566
05567 free(f->filename);
05568 free(f->cargo_list);
05569 free(f->railtype_list);
05570 free(f);
05571 }
05572
05573 _first_grffile = NULL;
05574 _cur_grffile = NULL;
05575 }
05576
05577 static void ResetNewGRFErrors()
05578 {
05579 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
05580 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
05581 free(c->error->custom_message);
05582 free(c->error->data);
05583 free(c->error);
05584 c->error = NULL;
05585 }
05586 }
05587 }
05588
05593 static void ResetNewGRFData()
05594 {
05595 CleanUpStrings();
05596 CleanUpGRFTownNames();
05597
05598
05599 SetupEngines();
05600
05601
05602 ResetBridges();
05603
05604
05605 ResetRailTypes();
05606
05607
05608 _gted = CallocT<GRFTempEngineData>(GetEnginePoolSize());
05609
05610
05611 memset(&_grm_engines, 0, sizeof(_grm_engines));
05612 memset(&_grm_cargos, 0, sizeof(_grm_cargos));
05613
05614
05615 ResetGenericCallbacks();
05616
05617
05618 ResetPriceBaseMultipliers();
05619
05620
05621 ResetCurrencies();
05622
05623
05624 ResetCustomHouses();
05625 ResetHouses();
05626
05627
05628 ResetCustomIndustries();
05629 ResetIndustries();
05630
05631
05632 ResetStationClasses();
05633 ResetCustomStations();
05634
05635
05636 memset(_water_feature, 0, sizeof(_water_feature));
05637
05638
05639 ClearSnowLine();
05640
05641
05642 ResetNewGRF();
05643
05644
05645 ResetNewGRFErrors();
05646
05647
05648 SetupCargoForClimate(_settings_game.game_creation.landscape);
05649
05650
05651 _misc_grf_features = 0;
05652 _traininfo_vehicle_pitch = 0;
05653 _traininfo_vehicle_width = 29;
05654
05655 _loaded_newgrf_features.has_2CC = false;
05656 _loaded_newgrf_features.has_newhouses = false;
05657 _loaded_newgrf_features.has_newindustries = false;
05658 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
05659
05660
05661 _grf_id_overrides.clear();
05662
05663 InitializeSoundPool();
05664 InitializeSpriteGroupPool();
05665 }
05666
05667 static void BuildCargoTranslationMap()
05668 {
05669 memset(_cur_grffile->cargo_map, 0xFF, sizeof(_cur_grffile->cargo_map));
05670
05671 for (CargoID c = 0; c < NUM_CARGO; c++) {
05672 const CargoSpec *cs = GetCargo(c);
05673 if (!cs->IsValid()) continue;
05674
05675 if (_cur_grffile->cargo_max == 0) {
05676
05677 _cur_grffile->cargo_map[c] = cs->bitnum;
05678 } else {
05679
05680 for (uint i = 0; i < _cur_grffile->cargo_max; i++) {
05681 if (cs->label == _cur_grffile->cargo_list[i]) {
05682 _cur_grffile->cargo_map[c] = i;
05683 break;
05684 }
05685 }
05686 }
05687 }
05688 }
05689
05690 static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
05691 {
05692 GRFFile *newfile = GetFileByFilename(config->filename);
05693 if (newfile != NULL) {
05694
05695 newfile->sprite_offset = sprite_offset;
05696 _cur_grffile = newfile;
05697 return;
05698 }
05699
05700 newfile = CallocT<GRFFile>(1);
05701
05702 if (newfile == NULL) error ("Out of memory");
05703
05704 newfile->filename = strdup(config->filename);
05705 newfile->sprite_offset = sprite_offset;
05706
05707
05708 assert(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
05709 newfile->param_end = config->num_params;
05710 memcpy(newfile->param, config->param, sizeof(newfile->param));
05711
05712 if (_first_grffile == NULL) {
05713 _cur_grffile = newfile;
05714 _first_grffile = newfile;
05715 } else {
05716 _cur_grffile->next = newfile;
05717 _cur_grffile = newfile;
05718 }
05719 }
05720
05721
05724 static const CargoLabel _default_refitmasks_rail[] = {
05725 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
05726 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
05727 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05728 'PLST', 'FZDR',
05729 0 };
05730
05731 static const CargoLabel _default_refitmasks_road[] = {
05732 0 };
05733
05734 static const CargoLabel _default_refitmasks_ships[] = {
05735 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
05736 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
05737 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
05738 'PLST', 'FZDR',
05739 0 };
05740
05741 static const CargoLabel _default_refitmasks_aircraft[] = {
05742 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
05743 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
05744 0 };
05745
05746 static const CargoLabel *_default_refitmasks[] = {
05747 _default_refitmasks_rail,
05748 _default_refitmasks_road,
05749 _default_refitmasks_ships,
05750 _default_refitmasks_aircraft,
05751 };
05752
05753
05757 static void CalculateRefitMasks()
05758 {
05759 Engine *e;
05760
05761 FOR_ALL_ENGINES(e) {
05762 EngineID engine = e->index;
05763 EngineInfo *ei = &e->info;
05764 uint32 mask = 0;
05765 uint32 not_mask = 0;
05766 uint32 xor_mask = 0;
05767
05768 if (ei->refit_mask != 0) {
05769 const GRFFile *file = e->grffile;
05770 if (file != NULL && file->cargo_max != 0) {
05771
05772 uint num_cargo = min(32, file->cargo_max);
05773 for (uint i = 0; i < num_cargo; i++) {
05774 if (!HasBit(ei->refit_mask, i)) continue;
05775
05776 CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
05777 if (c == CT_INVALID) continue;
05778
05779 SetBit(xor_mask, c);
05780 }
05781 } else {
05782
05783 for (CargoID c = 0; c < NUM_CARGO; c++) {
05784 const CargoSpec *cs = GetCargo(c);
05785 if (!cs->IsValid()) continue;
05786
05787 if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, c);
05788 }
05789 }
05790 }
05791
05792 if (_gted[engine].cargo_allowed != 0) {
05793
05794 for (CargoID i = 0; i < NUM_CARGO; i++) {
05795 const CargoSpec *cs = GetCargo(i);
05796 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i);
05797 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i);
05798 }
05799 } else if (xor_mask == 0) {
05800
05801 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
05802 const CargoLabel *cl = _default_refitmasks[e->type];
05803 for (uint i = 0;; i++) {
05804 if (cl[i] == 0) break;
05805
05806 CargoID cargo = GetCargoIDByLabel(cl[i]);
05807 if (cargo == CT_INVALID) continue;
05808
05809 SetBit(xor_mask, cargo);
05810 }
05811 }
05812 }
05813
05814 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
05815
05816
05817
05818 switch (e->type) {
05819 default: NOT_REACHED();
05820 case VEH_AIRCRAFT:
05821 if (FindFirstRefittableCargo(engine) == CT_INVALID) ei->climates = 0x80;
05822 break;
05823
05824 case VEH_TRAIN: {
05825 RailVehicleInfo *rvi = &e->u.rail;
05826 if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
05827 if (rvi->cargo_type == CT_INVALID) ei->climates = 0x80;
05828 break;
05829 }
05830 case VEH_ROAD: {
05831 RoadVehicleInfo *rvi = &e->u.road;
05832 if (rvi->cargo_type == CT_INVALID) rvi->cargo_type = FindFirstRefittableCargo(engine);
05833 if (rvi->cargo_type == CT_INVALID) ei->climates = 0x80;
05834 break;
05835 }
05836 case VEH_SHIP: {
05837 ShipVehicleInfo *svi = &e->u.ship;
05838 if (svi->cargo_type == CT_INVALID) svi->cargo_type = FindFirstRefittableCargo(engine);
05839 if (svi->cargo_type == CT_INVALID) ei->climates = 0x80;
05840 break;
05841 }
05842 }
05843 }
05844 }
05845
05850 static void FinaliseHouseArray()
05851 {
05852
05853
05854
05855
05856
05857
05858
05859
05860
05861 Year min_year = MAX_YEAR;
05862
05863 for (GRFFile *file = _first_grffile; file != NULL; file = file->next) {
05864 if (file->housespec == NULL) continue;
05865
05866 for (int i = 0; i < HOUSE_MAX; i++) {
05867 HouseSpec *hs = file->housespec[i];
05868
05869 if (hs == NULL) continue;
05870
05871 const HouseSpec *next1 = (i + 1 < HOUSE_MAX ? file->housespec[i + 1] : NULL);
05872 const HouseSpec *next2 = (i + 2 < HOUSE_MAX ? file->housespec[i + 2] : NULL);
05873 const HouseSpec *next3 = (i + 3 < HOUSE_MAX ? file->housespec[i + 3] : NULL);
05874
05875 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
05876 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
05877 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
05878 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
05879 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
05880 hs->enabled = false;
05881 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", file->filename, hs->local_id);
05882 continue;
05883 }
05884
05885
05886
05887
05888 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
05889 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
05890 hs->enabled = false;
05891 DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", file->filename, hs->local_id);
05892 continue;
05893 }
05894
05895 _house_mngr.SetEntitySpec(hs);
05896 if (hs->min_year < min_year) min_year = hs->min_year;
05897 }
05898 }
05899
05900 if (min_year != 0) {
05901 for (int i = 0; i < HOUSE_MAX; i++) {
05902 HouseSpec *hs = GetHouseSpecs(i);
05903
05904 if (hs->enabled && hs->min_year == min_year) hs->min_year = 0;
05905 }
05906 }
05907 }
05908
05912 static void FinaliseIndustriesArray()
05913 {
05914 for (GRFFile *file = _first_grffile; file != NULL; file = file->next) {
05915 if (file->industryspec != NULL) {
05916 for (int i = 0; i < NUM_INDUSTRYTYPES; i++) {
05917 IndustrySpec *indsp = file->industryspec[i];
05918
05919 if (indsp != NULL && indsp->enabled) {
05920 StringID strid;
05921
05922
05923
05924 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
05925 if (strid != STR_UNDEFINED) indsp->name = strid;
05926
05927 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
05928 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
05929
05930 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
05931 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
05932
05933 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
05934 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
05935
05936 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
05937 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
05938
05939 if (indsp->station_name != STR_NULL) {
05940
05941
05942 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
05943 if (strid != STR_UNDEFINED) indsp->station_name = strid;
05944 }
05945
05946 _industry_mngr.SetEntitySpec(indsp);
05947 _loaded_newgrf_features.has_newindustries = true;
05948 }
05949 }
05950 }
05951
05952 if (file->indtspec != NULL) {
05953 for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
05954 IndustryTileSpec *indtsp = file->indtspec[i];
05955 if (indtsp != NULL) {
05956 _industile_mngr.SetEntitySpec(indtsp);
05957 }
05958 }
05959 }
05960 }
05961
05962 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
05963 IndustrySpec *indsp = &_industry_specs[j];
05964 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
05965 for (uint i = 0; i < 3; i++) {
05966 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
05967 }
05968 }
05969 }
05970 }
05971
05972
05973
05974
05975
05976
05977
05978 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
05979 {
05980
05981
05982
05983
05984
05985
05986
05987
05988
05989
05990
05991
05992 static const SpecialSpriteHandler handlers[][GLS_END] = {
05993 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
05994 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
05995 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
05996 { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
05997 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
05998 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
05999 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
06000 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
06001 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
06002 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
06003 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
06004 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
06005 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
06006 { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
06007 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
06008 { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
06009 { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
06010 { SkipAct11,GRFUnsafe, SkipAct11, SkipAct11, SkipAct11, GRFSound, },
06011 { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
06012 { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
06013 };
06014
06015 GRFLocation location(_cur_grfconfig->grfid, _nfo_line);
06016
06017 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
06018 if (it == _grf_line_to_action6_sprite_override.end()) {
06019
06020
06021 FioReadBlock(buf, num);
06022 } else {
06023
06024 buf = _grf_line_to_action6_sprite_override[location];
06025 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
06026
06027
06028 FioSeekTo(num, SEEK_CUR);
06029 }
06030
06031 byte action = buf[0];
06032
06033 if (action == 0xFF) {
06034 grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
06035 GRFDataBlock(buf, num);
06036 } else if (action == 0xFE) {
06037 grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
06038 GRFImportBlock(buf, num);
06039 } else if (action >= lengthof(handlers)) {
06040 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
06041 } else if (handlers[action][stage] == NULL) {
06042 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
06043 } else {
06044 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
06045 handlers[action][stage](buf, num);
06046 }
06047 }
06048
06049
06050 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
06051 {
06052 const char *filename = config->filename;
06053 uint16 num;
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
06065 _cur_grffile = GetFileByFilename(filename);
06066 if (_cur_grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
06067 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
06068 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
06069 _cur_grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
06070 }
06071
06072 if (file_index > LAST_GRF_SLOT) {
06073 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
06074 config->status = GCS_DISABLED;
06075 config->error = CallocT<GRFError>(1);
06076 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06077 config->error->message = STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED;
06078 return;
06079 }
06080
06081 FioOpenFile(file_index, filename);
06082 _file_index = file_index;
06083 _palette_remap_grf[_file_index] = (config->windows_paletted != (_use_palette == PAL_WINDOWS));
06084
06085 _cur_grfconfig = config;
06086
06087 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
06088
06089
06090
06091
06092 if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
06093 FioReadDword();
06094 } else {
06095 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
06096 return;
06097 }
06098
06099 _skip_sprites = 0;
06100 _nfo_line = 0;
06101
06102 ReusableBuffer<byte> buf;
06103
06104 while ((num = FioReadWord()) != 0) {
06105 byte type = FioReadByte();
06106 _nfo_line++;
06107
06108 if (type == 0xFF) {
06109 if (_skip_sprites == 0) {
06110 DecodeSpecialSprite(buf.Allocate(num), num, stage);
06111
06112
06113 if (_skip_sprites == -1) break;
06114
06115 continue;
06116 } else {
06117 FioSkipBytes(num);
06118 }
06119 } else {
06120 if (_skip_sprites == 0) {
06121 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
06122 config->status = GCS_DISABLED;
06123 config->error = CallocT<GRFError>(1);
06124 config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
06125 config->error->message = STR_NEWGRF_ERROR_UNEXPECTED_SPRITE;
06126 break;
06127 }
06128
06129 FioSkipBytes(7);
06130 SkipSpriteData(type, num - 8);
06131 }
06132
06133 if (_skip_sprites > 0) _skip_sprites--;
06134 }
06135 }
06136
06144 static void ActivateOldShore()
06145 {
06146
06147
06148 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
06149
06150 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
06151 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1);
06152 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2);
06153 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3);
06154 DupSprite(SPR_ORIGINALSHORE_START , SPR_SHORE_BASE + 4);
06155 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6);
06156 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8);
06157 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9);
06158 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12);
06159 }
06160
06161 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
06162 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0);
06163 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5);
06164 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7);
06165 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10);
06166 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11);
06167 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13);
06168 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14);
06169 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15);
06170
06171
06172
06173 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16);
06174 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17);
06175 }
06176 }
06177
06178 void InitDepotWindowBlockSizes();
06179
06180 extern void InitGRFTownGeneratorNames();
06181
06182 static void AfterLoadGRFs()
06183 {
06184 for (StringIDToGRFIDMapping::iterator it = _string_to_grf_mapping.begin(); it != _string_to_grf_mapping.end(); it++) {
06185 *((*it).first) = MapGRFStringID((*it).second, *((*it).first));
06186 }
06187 _string_to_grf_mapping.clear();
06188
06189
06190 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
06191 free((*it).second);
06192 }
06193 _grf_line_to_action6_sprite_override.clear();
06194
06195
06196 CalculateRefitMasks();
06197
06198
06199 InitDepotWindowBlockSizes();
06200
06201
06202 FinaliseHouseArray();
06203
06204
06205 FinaliseIndustriesArray();
06206
06207
06208 BuildIndustriesLegend();
06209
06210
06211 InitGRFTownGeneratorNames();
06212
06213
06214 CommitVehicleListOrderChanges();
06215
06216
06217 ActivateOldShore();
06218
06219 Engine *e;
06220 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
06221 if (_gted[e->index].rv_max_speed != 0) {
06222
06223 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
06224 }
06225 }
06226
06227 SetYearEngineAgingStops();
06228
06229
06230 free(_gted);
06231 _grm_sprites.clear();
06232 }
06233
06234 void LoadNewGRF(uint load_index, uint file_index)
06235 {
06236
06237
06238
06239
06240 Date date = _date;
06241 Year year = _cur_year;
06242 DateFract date_fract = _date_fract;
06243 uint16 tick_counter = _tick_counter;
06244 byte display_opt = _display_opt;
06245
06246 if (_networking) {
06247 _cur_year = _settings_game.game_creation.starting_year;
06248 _date = ConvertYMDToDate(_cur_year, 0, 1);
06249 _date_fract = 0;
06250 _tick_counter = 0;
06251 _display_opt = 0;
06252 }
06253
06254 InitializeGRFSpecial();
06255
06256 ResetNewGRFData();
06257
06258
06259
06260
06261
06262
06263
06264
06265 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06266 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
06267 }
06268
06269 _cur_spriteid = load_index;
06270
06271
06272
06273
06274 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
06275
06276
06277 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06278 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
06279 }
06280
06281 uint slot = file_index;
06282
06283 _cur_stage = stage;
06284 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
06285 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
06286 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
06287
06288 if (!FioCheckFileExists(c->filename)) {
06289 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
06290 c->status = GCS_NOT_FOUND;
06291 continue;
06292 }
06293
06294 if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
06295 LoadNewGRFFile(c, slot++, stage);
06296 if (stage == GLS_RESERVE) {
06297 SetBit(c->flags, GCF_RESERVED);
06298 } else if (stage == GLS_ACTIVATION) {
06299 ClrBit(c->flags, GCF_RESERVED);
06300 assert(GetFileByGRFID(c->grfid) == _cur_grffile);
06301 ClearTemporaryNewGRFData(_cur_grffile);
06302 BuildCargoTranslationMap();
06303 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
06304 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
06305
06306 ClearTemporaryNewGRFData(_cur_grffile);
06307 }
06308 }
06309 }
06310
06311
06312 AfterLoadGRFs();
06313
06314
06315 _cur_year = year;
06316 _date = date;
06317 _date_fract = date_fract;
06318 _tick_counter = tick_counter;
06319 _display_opt = display_opt;
06320 }
06321
06322 bool HasGrfMiscBit(GrfMiscBit bit)
06323 {
06324 return HasBit(_misc_grf_features, bit);
06325 }