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