mirror of https://github.com/OpenTTD/OpenTTD.git
(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;
|
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);
|
const CargoSpec *GetCargo(CargoID c);
|
||||||
/* Get the cargo ID of a cargo bitnum */
|
/* Get the cargo ID of a cargo bitnum */
|
||||||
CargoID GetCargoIDByBitnum(byte bitnum);
|
CargoID GetCargoIDByBitnum(byte bitnum);
|
||||||
|
/* Get the cargo ID with the cargo label */
|
||||||
|
CargoID GetCargoIDByLabel(CargoLabel cl);
|
||||||
|
|
||||||
|
|
||||||
#endif /* CARGOTYPE_H */
|
#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) */
|
/* Set if any vehicle is loaded which uses 2cc (two company colours) */
|
||||||
bool _have_2cc = false;
|
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 {
|
typedef enum GrfDataType {
|
||||||
GDT_SOUND,
|
GDT_SOUND,
|
||||||
|
@ -1189,6 +1193,12 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
|
||||||
}
|
}
|
||||||
break;
|
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
|
case 0x0A: // Currency display names
|
||||||
FOR_EACH_OBJECT {
|
FOR_EACH_OBJECT {
|
||||||
uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
|
uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
|
||||||
|
@ -1273,7 +1283,6 @@ static bool GlobalVarChangeInfo(uint gvid, int numinfo, int prop, byte **bufp, i
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x09: // Cargo translation table
|
|
||||||
case 0x10: // 12 * 32 * B Snow line height table
|
case 0x10: // 12 * 32 * B Snow line height table
|
||||||
default:
|
default:
|
||||||
ret = true;
|
ret = true;
|
||||||
|
@ -1501,6 +1510,55 @@ static void SafeChangeInfo(byte *buf, int len)
|
||||||
_skip_sprites = -1;
|
_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
|
#undef FOR_EACH_OBJECT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1834,6 +1892,38 @@ static void NewSpriteGroup(byte *buf, int len)
|
||||||
_cur_grffile->spritegroups[setid] = group;
|
_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 */
|
/* Action 0x03 */
|
||||||
static void FeatureMapSpriteGroup(byte *buf, int len)
|
static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||||
{
|
{
|
||||||
|
@ -1905,13 +1995,8 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctype == 0xFE) ctype = GC_DEFAULT_NA;
|
ctype = TranslateCargo(feature, ctype);
|
||||||
if (ctype == 0xFF) ctype = GC_PURCHASE;
|
if (ctype == CT_INVALID) continue;
|
||||||
|
|
||||||
if (ctype >= NUM_GLOBAL_CID) {
|
|
||||||
grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
|
statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
|
||||||
}
|
}
|
||||||
|
@ -1987,12 +2072,8 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctype == GC_INVALID) ctype = GC_PURCHASE;
|
ctype = TranslateCargo(feature, ctype);
|
||||||
|
if (ctype == CT_INVALID) continue;
|
||||||
if (ctype >= NUM_GLOBAL_CID) {
|
|
||||||
grfmsg(1, "FeatureMapSpriteGroup: Cargo type %d out of range, skipping.", ctype);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wagover) {
|
if (wagover) {
|
||||||
SetWagonOverrideSprites(engine, ctype, _cur_grffile->spritegroups[groupid], last_engines, last_engines_count);
|
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 */
|
/* Set up the default cargo types */
|
||||||
SetupCargoForClimate(_opt.landscape);
|
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 */
|
/* Reset misc GRF features and train list display variables */
|
||||||
_misc_grf_features = 0;
|
_misc_grf_features = 0;
|
||||||
_traininfo_vehicle_pitch = 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.
|
* 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. */
|
* In other stages we skip action 0x10 since it's already dealt with. */
|
||||||
static const SpecialSpriteHandler handlers[][GLS_END] = {
|
static const SpecialSpriteHandler handlers[][GLS_END] = {
|
||||||
/* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, FeatureChangeInfo, },
|
/* 0x00 */ { NULL, SafeChangeInfo, NULL, InitChangeInfo, FeatureChangeInfo, },
|
||||||
/* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteSet, },
|
/* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteSet, },
|
||||||
/* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteGroup, },
|
/* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteGroup, },
|
||||||
/* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, FeatureMapSpriteGroup, },
|
/* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, FeatureMapSpriteGroup, },
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "station.h"
|
#include "station.h"
|
||||||
#include "newgrf_config.h"
|
#include "newgrf_config.h"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
#include "cargotype.h"
|
||||||
|
|
||||||
typedef enum GrfLoadingStage {
|
typedef enum GrfLoadingStage {
|
||||||
GLS_FILESCAN,
|
GLS_FILESCAN,
|
||||||
|
@ -60,6 +61,9 @@ typedef struct GRFFile {
|
||||||
uint param_end; /// one more than the highest set parameter
|
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.
|
GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array.
|
||||||
|
|
||||||
|
uint8 cargo_max;
|
||||||
|
CargoLabel *cargo_list;
|
||||||
} GRFFile;
|
} GRFFile;
|
||||||
|
|
||||||
extern GRFFile *_first_grffile;
|
extern GRFFile *_first_grffile;
|
||||||
|
|
Loading…
Reference in New Issue