mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-02-07 06:46:43 +00:00
(svn r8886) -Codechange: (NewGRF) Add (partial) cargo translation table support, applied to action 3s only.
This commit is contained in:
parent
0cf5ebee79
commit
a23b4594ed
@ -75,3 +75,14 @@ bool CargoSpec::IsValid() const
|
||||
{
|
||||
return bitnum != INVALID_CARGO;
|
||||
}
|
||||
|
||||
|
||||
CargoID GetCargoIDByLabel(CargoLabel cl)
|
||||
{
|
||||
for (CargoID c = 0; c < lengthof(_cargo); c++) {
|
||||
if (_cargo[c].label == cl) return c;
|
||||
}
|
||||
|
||||
/* No matching label was found, so it is invalid */
|
||||
return CT_INVALID;
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ void SetupCargoForClimate(LandscapeID l);
|
||||
const CargoSpec *GetCargo(CargoID c);
|
||||
/* Get the cargo ID of a cargo bitnum */
|
||||
CargoID GetCargoIDByBitnum(byte bitnum);
|
||||
/* Get the cargo ID with the cargo label */
|
||||
CargoID GetCargoIDByLabel(CargoLabel cl);
|
||||
|
||||
|
||||
#endif /* CARGOTYPE_H */
|
||||
|
118
src/newgrf.cpp
118
src/newgrf.cpp
@ -68,6 +68,10 @@ static byte *_preload_sprite = NULL;
|
||||
/* Set if any vehicle is loaded which uses 2cc (two company colours) */
|
||||
bool _have_2cc = false;
|
||||
|
||||
/* Default cargo translation table. By default there are 27 possible cargo types */
|
||||
static const uint _default_cargo_max = 27;
|
||||
static CargoLabel _default_cargo_list[_default_cargo_max];
|
||||
|
||||
|
||||
typedef enum GrfDataType {
|
||||
GDT_SOUND,
|
||||
@ -1189,6 +1193,12 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09: /* Cargo translation table */
|
||||
/* This is loaded during the initialisation stage, so just skip it here. */
|
||||
/* Each entry is 4 bytes. */
|
||||
buf += numinfo * 4;
|
||||
break;
|
||||
|
||||
case 0x0A: // Currency display names
|
||||
FOR_EACH_OBJECT {
|
||||
uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
|
||||
@ -1273,7 +1283,6 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09: // Cargo translation table
|
||||
case 0x10: // 12 * 32 * B Snow line height table
|
||||
default:
|
||||
ret = true;
|
||||
@ -1501,6 +1510,55 @@ static void SafeChangeInfo(byte *buf, int len)
|
||||
_skip_sprites = -1;
|
||||
}
|
||||
|
||||
/* Action 0x00 (GLS_INIT) */
|
||||
static void InitChangeInfo(byte *buf, int len)
|
||||
{
|
||||
byte *bufend = buf + len;
|
||||
uint8 feature;
|
||||
uint8 numprops;
|
||||
uint8 numinfo;
|
||||
uint8 index;
|
||||
|
||||
if (len == 1) {
|
||||
grfmsg(8, "Silently ignoring one-byte special sprite 0x00");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_length(len, 6, "InitChangeInfo")) return;
|
||||
buf++;
|
||||
feature = grf_load_byte(&buf);
|
||||
numprops = grf_load_byte(&buf);
|
||||
numinfo = grf_load_byte(&buf);
|
||||
index = grf_load_byte(&buf);
|
||||
|
||||
while (numprops-- && buf < bufend) {
|
||||
uint8 prop = grf_load_byte(&buf);
|
||||
|
||||
switch (feature) {
|
||||
case GSF_GLOBALVAR:
|
||||
switch (prop) {
|
||||
case 0x09: /* Cargo Translation Table */
|
||||
if (index != 0) {
|
||||
grfmsg(1, "InitChangeInfo: Cargo translation table must start at zero");
|
||||
return;
|
||||
}
|
||||
|
||||
free(_cur_grffile->cargo_list);
|
||||
_cur_grffile->cargo_max = numinfo;
|
||||
_cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
|
||||
|
||||
int i;
|
||||
FOR_EACH_OBJECT {
|
||||
CargoLabel cl = grf_load_dword(&buf);
|
||||
_cur_grffile->cargo_list[i] = BSWAP32(cl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef FOR_EACH_OBJECT
|
||||
|
||||
/**
|
||||
@ -1834,6 +1892,38 @@ static void NewSpriteGroup(byte *buf, int len)
|
||||
_cur_grffile->spritegroups[setid] = group;
|
||||
}
|
||||
|
||||
static CargoID TranslateCargo(uint8 feature, uint8 ctype)
|
||||
{
|
||||
/* Special cargo types for purchase list and stations */
|
||||
if (feature == GSF_STATION && ctype == 0xFE) return GC_DEFAULT_NA;
|
||||
if (ctype == 0xFF) return GC_PURCHASE;
|
||||
|
||||
/* Check if the cargo type is out of bounds of the cargo translation table */
|
||||
if (ctype >= (_cur_grffile->cargo_max == 0 ? _default_cargo_max : _cur_grffile->cargo_max)) {
|
||||
grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range (max %d), skipping.", ctype, (_cur_grffile->cargo_max == 0 ? _default_cargo_max : _cur_grffile->cargo_max) - 1);
|
||||
return CT_INVALID;
|
||||
}
|
||||
|
||||
/* Look up the cargo label from the translation table */
|
||||
CargoLabel cl = _cur_grffile->cargo_max == 0 ? _default_cargo_list[ctype] : _cur_grffile->cargo_list[ctype];
|
||||
if (cl == 0) {
|
||||
grfmsg(5, "FeatureMapSpriteGroup: Cargo type %d not available in this climate, skipping.", ctype);
|
||||
return CT_INVALID;
|
||||
}
|
||||
|
||||
ctype = GetCargoIDByLabel(cl);
|
||||
if (ctype == CT_INVALID) {
|
||||
grfmsg(5, "FeatureMapSpriteGroup: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
|
||||
return CT_INVALID;
|
||||
}
|
||||
|
||||
/* Remap back to global cargo */
|
||||
ctype = GetCargo(ctype)->bitnum;
|
||||
|
||||
grfmsg(6, "FeatureMapSpriteGroup: 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);
|
||||
return ctype;
|
||||
}
|
||||
|
||||
/* Action 0x03 */
|
||||
static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||
{
|
||||
@ -1905,13 +1995,8 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctype == 0xFE) ctype = GC_DEFAULT_NA;
|
||||
if (ctype == 0xFF) ctype = GC_PURCHASE;
|
||||
|
||||
if (ctype >= NUM_GLOBAL_CID) {
|
||||
grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
|
||||
continue;
|
||||
}
|
||||
ctype = TranslateCargo(feature, ctype);
|
||||
if (ctype == CT_INVALID) continue;
|
||||
|
||||
statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
|
||||
}
|
||||
@ -1987,12 +2072,8 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctype == GC_INVALID) ctype = GC_PURCHASE;
|
||||
|
||||
if (ctype >= NUM_GLOBAL_CID) {
|
||||
grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
|
||||
continue;
|
||||
}
|
||||
ctype = TranslateCargo(feature, ctype);
|
||||
if (ctype == CT_INVALID) continue;
|
||||
|
||||
if (wagover) {
|
||||
SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
|
||||
@ -3589,6 +3670,13 @@ static void ResetNewGRFData(void)
|
||||
/* Set up the default cargo types */
|
||||
SetupCargoForClimate(_opt.landscape);
|
||||
|
||||
/* Generate default cargo translation table */
|
||||
memset(_default_cargo_list, 0, sizeof(_default_cargo_list));
|
||||
for (CargoID c = 0; c != NUM_CARGO; c++) {
|
||||
const CargoSpec *cs = GetCargo(c);
|
||||
if (cs->IsValid()) _default_cargo_list[cs->bitnum] = cs->label;
|
||||
}
|
||||
|
||||
/* Reset misc GRF features and train list display variables */
|
||||
_misc_grf_features = 0;
|
||||
_traininfo_vehicle_pitch = 0;
|
||||
@ -3755,7 +3843,7 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
|
||||
* is not in memory and scanning the file every time would be too expensive.
|
||||
* In other stages we skip action 0x10 since it's already dealt with. */
|
||||
static const SpecialSpriteHandler handlers[][GLS_END] = {
|
||||
/* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, FeatureChangeInfo, },
|
||||
/* 0x00 */ { NULL, SafeChangeInfo, NULL, InitChangeInfo, FeatureChangeInfo, },
|
||||
/* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteSet, },
|
||||
/* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteGroup, },
|
||||
/* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, FeatureMapSpriteGroup, },
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "station.h"
|
||||
#include "newgrf_config.h"
|
||||
#include "helpers.hpp"
|
||||
#include "cargotype.h"
|
||||
|
||||
typedef enum GrfLoadingStage {
|
||||
GLS_FILESCAN,
|
||||
@ -60,6 +61,9 @@ typedef struct GRFFile {
|
||||
uint param_end; /// one more than the highest set parameter
|
||||
|
||||
GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array.
|
||||
|
||||
uint8 cargo_max;
|
||||
CargoLabel *cargo_list;
|
||||
} GRFFile;
|
||||
|
||||
extern GRFFile *_first_grffile;
|
||||
|
Loading…
Reference in New Issue
Block a user