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