|
|
@ -50,11 +50,20 @@ static void CDECL grfmsg(enum grfmsg_severity severity, const char *str, ...)
|
|
|
|
DEBUG(grf, 2) ("[%s][%s] %s", _cur_grffile, severitystr[severity], buf);
|
|
|
|
DEBUG(grf, 2) ("[%s][%s] %s", _cur_grffile, severitystr[severity], buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define check_length(real, wanted, where) \
|
|
|
|
|
|
|
|
do { \
|
|
|
|
|
|
|
|
if (real < wanted) { \
|
|
|
|
|
|
|
|
grfmsg(GMS_ERROR, "%s: Invalid special sprite length %d (expected %d)!", where, real, wanted); \
|
|
|
|
|
|
|
|
return; \
|
|
|
|
|
|
|
|
} \
|
|
|
|
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static byte INLINE grf_load_byte(byte **buf) {
|
|
|
|
static byte INLINE grf_load_byte(byte **buf) {
|
|
|
|
return *(*buf)++;
|
|
|
|
return *(*buf)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static uint16 grf_load_word(byte **buf)
|
|
|
|
static uint16 grf_load_word(byte **buf)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
uint16 val;
|
|
|
|
uint16 val;
|
|
|
@ -77,6 +86,7 @@ static uint16 grf_load_dword(byte **buf)
|
|
|
|
return val;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef int (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
|
|
|
|
typedef int (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
|
|
|
|
|
|
|
|
|
|
|
|
#define foreach_engine for (i = 0; i < numinfo; i++)
|
|
|
|
#define foreach_engine for (i = 0; i < numinfo; i++)
|
|
|
@ -447,95 +457,98 @@ static void VehicleChangeInfo(byte *buf, int len)
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8 feature;
|
|
|
|
|
|
|
|
uint8 numprops;
|
|
|
|
|
|
|
|
uint8 numinfo;
|
|
|
|
|
|
|
|
byte engine;
|
|
|
|
|
|
|
|
EngineInfo *ei;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_length(len, 6, "VehicleChangeInfo");
|
|
|
|
|
|
|
|
feature = buf[1];
|
|
|
|
|
|
|
|
numprops = buf[2];
|
|
|
|
|
|
|
|
numinfo = buf[3];
|
|
|
|
|
|
|
|
engine = buf[4];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (feature != 0 && feature != 2) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "VehicleChangeInfo: Unsupported vehicle type %x, skipping.", feature);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (len > 5) {
|
|
|
|
ei = &_engine_info[engine + _vehshifts[feature]];
|
|
|
|
uint8 feature = buf[1];
|
|
|
|
|
|
|
|
uint8 numprops = buf[2];
|
|
|
|
|
|
|
|
uint8 numinfo = buf[3];
|
|
|
|
|
|
|
|
byte engine = buf[4];
|
|
|
|
|
|
|
|
EngineInfo *ei;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (feature != 0 && feature != 2) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "VehicleChangeInfo: Unsupported vehicle type %x, skipping.", feature);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ei = &_engine_info[engine + _vehshifts[feature]];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf += 5;
|
|
|
|
buf += 5;
|
|
|
|
|
|
|
|
|
|
|
|
while (numprops-- && buf < bufend) {
|
|
|
|
while (numprops-- && buf < bufend) {
|
|
|
|
uint8 prop = grf_load_byte(&buf);
|
|
|
|
uint8 prop = grf_load_byte(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
switch (prop) {
|
|
|
|
switch (prop) {
|
|
|
|
case 0x00: {
|
|
|
|
case 0x00: {
|
|
|
|
/* Introduction date */
|
|
|
|
/* Introduction date */
|
|
|
|
foreach_engine {
|
|
|
|
foreach_engine {
|
|
|
|
uint16 date = grf_load_word(&buf);
|
|
|
|
uint16 date = grf_load_word(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
ei[i].base_intro = date;
|
|
|
|
ei[i].base_intro = date;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 0x02: {
|
|
|
|
break;
|
|
|
|
/* Decay speed */
|
|
|
|
}
|
|
|
|
foreach_engine {
|
|
|
|
case 0x02: {
|
|
|
|
uint8 decay = grf_load_byte(&buf);
|
|
|
|
/* Decay speed */
|
|
|
|
|
|
|
|
foreach_engine {
|
|
|
|
|
|
|
|
uint8 decay = grf_load_byte(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
ei[i].unk2 &= 0x80;
|
|
|
|
ei[i].unk2 &= 0x80;
|
|
|
|
ei[i].unk2 |= decay & 0x7f;
|
|
|
|
ei[i].unk2 |= decay & 0x7f;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 0x03: {
|
|
|
|
break;
|
|
|
|
/* Vehicle life */
|
|
|
|
}
|
|
|
|
foreach_engine {
|
|
|
|
case 0x03: {
|
|
|
|
uint8 life = grf_load_byte(&buf);
|
|
|
|
/* Vehicle life */
|
|
|
|
|
|
|
|
foreach_engine {
|
|
|
|
|
|
|
|
uint8 life = grf_load_byte(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
ei[i].lifelength = life;
|
|
|
|
ei[i].lifelength = life;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 0x04: {
|
|
|
|
break;
|
|
|
|
/* Model life */
|
|
|
|
}
|
|
|
|
foreach_engine {
|
|
|
|
case 0x04: {
|
|
|
|
uint8 life = grf_load_byte(&buf);
|
|
|
|
/* Model life */
|
|
|
|
|
|
|
|
foreach_engine {
|
|
|
|
|
|
|
|
uint8 life = grf_load_byte(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
ei[i].base_life = life;
|
|
|
|
ei[i].base_life = life;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 0x06: {
|
|
|
|
break;
|
|
|
|
/* Climates available */
|
|
|
|
}
|
|
|
|
foreach_engine {
|
|
|
|
case 0x06: {
|
|
|
|
uint8 climates = grf_load_byte(&buf);
|
|
|
|
/* Climates available */
|
|
|
|
|
|
|
|
foreach_engine {
|
|
|
|
|
|
|
|
uint8 climates = grf_load_byte(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
ei[i].railtype_climates &= 0xf0;
|
|
|
|
ei[i].railtype_climates &= 0xf0;
|
|
|
|
ei[i].railtype_climates |= climates;
|
|
|
|
ei[i].railtype_climates |= climates;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case 0x07: { /* TODO */
|
|
|
|
break;
|
|
|
|
/* Loading speed */
|
|
|
|
}
|
|
|
|
/* Hyronymus explained me what does
|
|
|
|
case 0x07: { /* TODO */
|
|
|
|
* this mean and insists on having a
|
|
|
|
/* Loading speed */
|
|
|
|
* credit ;-). --pasky */
|
|
|
|
/* Hyronymus explained me what does
|
|
|
|
/* TODO: This needs to be supported by
|
|
|
|
* this mean and insists on having a
|
|
|
|
* LoadUnloadVehicle() first. */
|
|
|
|
* credit ;-). --pasky */
|
|
|
|
foreach_engine {
|
|
|
|
/* TODO: This needs to be supported by
|
|
|
|
grf_load_byte(&buf);
|
|
|
|
* LoadUnloadVehicle() first. */
|
|
|
|
}
|
|
|
|
foreach_engine {
|
|
|
|
goto ignoring;
|
|
|
|
grf_load_byte(&buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
goto ignoring;
|
|
|
|
{
|
|
|
|
}
|
|
|
|
if (handler[feature](engine, numinfo, prop, &buf, bufend - buf)) {
|
|
|
|
default:
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (handler[feature](engine, numinfo, prop, &buf, bufend - buf)) {
|
|
|
|
ignoring:
|
|
|
|
ignoring:
|
|
|
|
grfmsg(GMS_NOTICE, "VehicleChangeInfo: Ignoring property %x (not implemented).", prop);
|
|
|
|
grfmsg(GMS_NOTICE, "VehicleChangeInfo: Ignoring property %x (not implemented).", prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef shift_buf
|
|
|
|
#undef shift_buf
|
|
|
@ -577,21 +590,21 @@ static void SpriteNewSet(byte *buf, int len)
|
|
|
|
* For stations, must be 12 (hex) for the eighteen
|
|
|
|
* For stations, must be 12 (hex) for the eighteen
|
|
|
|
* different sprites that make up a station */
|
|
|
|
* different sprites that make up a station */
|
|
|
|
/* TODO: No stations support. */
|
|
|
|
/* TODO: No stations support. */
|
|
|
|
|
|
|
|
uint8 feature;
|
|
|
|
|
|
|
|
|
|
|
|
if (len == 4) {
|
|
|
|
check_length(len, 4, "SpriteNewSet");
|
|
|
|
uint8 feature = buf[1];
|
|
|
|
feature = buf[1];
|
|
|
|
|
|
|
|
|
|
|
|
if (feature == 4) {
|
|
|
|
if (feature == 4) {
|
|
|
|
_spriteset_start = 0;
|
|
|
|
_spriteset_start = 0;
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSet: Stations unsupported, skipping.");
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSet: Stations unsupported, skipping.");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_spriteset_start = _cur_spriteid + 1;
|
|
|
|
|
|
|
|
_spriteset_feature = feature;
|
|
|
|
|
|
|
|
_spriteset_numsets = buf[2];
|
|
|
|
|
|
|
|
_spriteset_numents = buf[3];
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_spriteset_start = _cur_spriteid + 1;
|
|
|
|
|
|
|
|
_spriteset_feature = feature;
|
|
|
|
|
|
|
|
_spriteset_numsets = buf[2];
|
|
|
|
|
|
|
|
_spriteset_numents = buf[3];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Action 0x02 */
|
|
|
|
/* Action 0x02 */
|
|
|
@ -613,94 +626,97 @@ static void SpriteNewSuperset(byte *buf, int len)
|
|
|
|
/* TODO: Also, empty sprites aren't handled for now. Need to investigate
|
|
|
|
/* TODO: Also, empty sprites aren't handled for now. Need to investigate
|
|
|
|
* the "opacity" rules for these, that is which sprite to fall back to
|
|
|
|
* the "opacity" rules for these, that is which sprite to fall back to
|
|
|
|
* when. --pasky */
|
|
|
|
* when. --pasky */
|
|
|
|
|
|
|
|
uint8 feature;
|
|
|
|
|
|
|
|
uint8 setid;
|
|
|
|
|
|
|
|
uint8 numloaded;
|
|
|
|
|
|
|
|
uint8 numloading;
|
|
|
|
|
|
|
|
struct SpriteSuperSet *superset;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
if (bufend - buf > 4) {
|
|
|
|
check_length(len, 5, "SpriteNewSuperset");
|
|
|
|
uint8 feature = buf[1];
|
|
|
|
feature = buf[1];
|
|
|
|
uint8 setid = buf[2];
|
|
|
|
setid = buf[2];
|
|
|
|
uint8 numloaded = buf[3];
|
|
|
|
numloaded = buf[3];
|
|
|
|
uint8 numloading = buf[4];
|
|
|
|
numloading = buf[4];
|
|
|
|
struct SpriteSuperSet *superset;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (feature == 4) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: Stations unsupported, skipping.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (numloaded == 0x81) {
|
|
|
|
|
|
|
|
// XXX: This is _VERY_ ad hoc just to handle Dm3. And that is
|
|
|
|
|
|
|
|
// a semi-futile ask because the great Patchman himself says
|
|
|
|
|
|
|
|
// this is just buggy. It dereferences last (first) byte of
|
|
|
|
|
|
|
|
// a schedule list pointer of the vehicle and if it's 0xff
|
|
|
|
|
|
|
|
// it uses superset 01, otherwise it uses superset 00. Now
|
|
|
|
|
|
|
|
// if _you_ understand _that_... We just assume it is never
|
|
|
|
|
|
|
|
// 0xff and therefore go for superset 00. --pasky
|
|
|
|
|
|
|
|
uint8 var = buf[4];
|
|
|
|
|
|
|
|
//uint8 shiftnum = buf[5];
|
|
|
|
|
|
|
|
//uint8 andmask = buf[6];
|
|
|
|
|
|
|
|
uint8 nvar = buf[7];
|
|
|
|
|
|
|
|
//uint32 val;
|
|
|
|
|
|
|
|
uint16 def;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset(0x81): Unsupported variable %x. Using default cid.", var);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//val = (0xff << shiftnum) & andmask;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Go for the default.
|
|
|
|
|
|
|
|
if (setid >= _spritesset_count) {
|
|
|
|
|
|
|
|
_spritesset_count = setid + 1;
|
|
|
|
|
|
|
|
_spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
buf += 8 + nvar * 4;
|
|
|
|
|
|
|
|
def = grf_load_word(&buf);
|
|
|
|
|
|
|
|
_spritesset[setid] = _spritesset[def];
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (numloaded & 0x80) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset(0x%x): Unsupported special superset.", numloaded);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!_spriteset_start) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: No sprite set to work on! Skipping.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_spriteset_feature != feature) {
|
|
|
|
if (feature == 4) {
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: Superset feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature);
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: Stations unsupported, skipping.");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (numloaded == 0x81) {
|
|
|
|
|
|
|
|
// XXX: This is _VERY_ ad hoc just to handle Dm3. And that is
|
|
|
|
|
|
|
|
// a semi-futile ask because the great Patchman himself says
|
|
|
|
|
|
|
|
// this is just buggy. It dereferences last (first) byte of
|
|
|
|
|
|
|
|
// a schedule list pointer of the vehicle and if it's 0xff
|
|
|
|
|
|
|
|
// it uses superset 01, otherwise it uses superset 00. Now
|
|
|
|
|
|
|
|
// if _you_ understand _that_... We just assume it is never
|
|
|
|
|
|
|
|
// 0xff and therefore go for superset 00. --pasky
|
|
|
|
|
|
|
|
uint8 var = buf[4];
|
|
|
|
|
|
|
|
//uint8 shiftnum = buf[5];
|
|
|
|
|
|
|
|
//uint8 andmask = buf[6];
|
|
|
|
|
|
|
|
uint8 nvar = buf[7];
|
|
|
|
|
|
|
|
//uint32 val;
|
|
|
|
|
|
|
|
uint16 def;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset(0x81): Unsupported variable %x. Using default cid.", var);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//val = (0xff << shiftnum) & andmask;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Go for the default.
|
|
|
|
if (setid >= _spritesset_count) {
|
|
|
|
if (setid >= _spritesset_count) {
|
|
|
|
_spritesset_count = setid + 1;
|
|
|
|
_spritesset_count = setid + 1;
|
|
|
|
_spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet));
|
|
|
|
_spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
superset = &_spritesset[setid];
|
|
|
|
buf += 8 + nvar * 4;
|
|
|
|
memset(superset, 0, sizeof(struct SpriteSuperSet));
|
|
|
|
def = grf_load_word(&buf);
|
|
|
|
superset->sprites_per_set = _spriteset_numents;
|
|
|
|
_spritesset[setid] = _spritesset[def];
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
buf += 5;
|
|
|
|
} else if (numloaded & 0x80) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset(0x%x): Unsupported special superset.", numloaded);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; buf < bufend && i < numloaded; i++) {
|
|
|
|
if (!_spriteset_start) {
|
|
|
|
uint16 spriteset_id = grf_load_word(&buf);
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: No sprite set to work on! Skipping.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_spritesset[setid].loaded_count > 16) {
|
|
|
|
if (_spriteset_feature != feature) {
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid);
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: Superset feature %x doesn't match set feature %x! Skipping.", feature, _spriteset_feature);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
superset->loaded[superset->loaded_count++]
|
|
|
|
|
|
|
|
= _spriteset_start + spriteset_id * _spriteset_numents;
|
|
|
|
if (setid >= _spritesset_count) {
|
|
|
|
|
|
|
|
_spritesset_count = setid + 1;
|
|
|
|
|
|
|
|
_spritesset = realloc(_spritesset, _spritesset_count * sizeof(struct SpriteSuperSet));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
superset = &_spritesset[setid];
|
|
|
|
|
|
|
|
memset(superset, 0, sizeof(struct SpriteSuperSet));
|
|
|
|
|
|
|
|
superset->sprites_per_set = _spriteset_numents;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf += 5;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; buf < bufend && i < numloaded; i++) {
|
|
|
|
|
|
|
|
uint16 spriteset_id = grf_load_word(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_spritesset[setid].loaded_count > 16) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
superset->loaded[superset->loaded_count++]
|
|
|
|
|
|
|
|
= _spriteset_start + spriteset_id * _spriteset_numents;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; buf < bufend && i < numloading; i++) {
|
|
|
|
for (i = 0; buf < bufend && i < numloading; i++) {
|
|
|
|
uint16 spriteset_id = grf_load_word(&buf);
|
|
|
|
uint16 spriteset_id = grf_load_word(&buf);
|
|
|
|
|
|
|
|
|
|
|
|
if (_spritesset[setid].loading_count > 16) {
|
|
|
|
if (_spritesset[setid].loading_count > 16) {
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid);
|
|
|
|
grfmsg(GMS_WARN, "SpriteNewSuperset: More than 16 sprites in superset %x, skipping.", setid);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
superset->loading[superset->loading_count++] = _spriteset_start + spriteset_id * _spriteset_numents;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
superset->loading[superset->loading_count++] = _spriteset_start + spriteset_id * _spriteset_numents;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -727,79 +743,82 @@ static void VehicleMapSpriteSuperset(byte *buf, int len)
|
|
|
|
|
|
|
|
|
|
|
|
static byte *last_engines;
|
|
|
|
static byte *last_engines;
|
|
|
|
static int last_engines_count;
|
|
|
|
static int last_engines_count;
|
|
|
|
|
|
|
|
uint8 feature;
|
|
|
|
|
|
|
|
uint8 idcount;
|
|
|
|
|
|
|
|
int wagover;
|
|
|
|
|
|
|
|
uint8 cidcount;
|
|
|
|
|
|
|
|
int c, i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_length(len, 7, "VehicleMapSpriteSuperset");
|
|
|
|
|
|
|
|
feature = buf[1];
|
|
|
|
|
|
|
|
idcount = buf[2] & 0x7f;
|
|
|
|
|
|
|
|
wagover = buf[2] & 0x80;
|
|
|
|
|
|
|
|
cidcount = buf[3 + idcount];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (feature == 4) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Stations unsupported, skipping.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (bufend - buf > 6) {
|
|
|
|
// FIXME: Tropicset contains things like:
|
|
|
|
uint8 feature = buf[1];
|
|
|
|
// 03 00 01 19 01 00 00 00 00 - this is missing one 00 at the end,
|
|
|
|
uint8 idcount = buf[2] & 0x7f;
|
|
|
|
// what should we exactly do with that? --pasky
|
|
|
|
int wagover = buf[2] & 0x80;
|
|
|
|
|
|
|
|
uint8 cidcount = buf[3 + idcount];
|
|
|
|
|
|
|
|
int c, i;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (feature == 4) {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Stations unsupported, skipping.");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: Tropicset contains things like:
|
|
|
|
|
|
|
|
// 03 00 01 19 01 00 00 00 00 - this is missing one 00 at the end,
|
|
|
|
|
|
|
|
// what should we exactly do with that? --pasky
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!_spriteset_start || !_spritesset) {
|
|
|
|
if (!_spriteset_start || !_spritesset) {
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: No sprite set to work on! Skipping.");
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: No sprite set to work on! Skipping.");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!wagover && last_engines_count != idcount) {
|
|
|
|
if (!wagover && last_engines_count != idcount) {
|
|
|
|
last_engines = realloc(last_engines, idcount);
|
|
|
|
last_engines = realloc(last_engines, idcount);
|
|
|
|
last_engines_count = idcount;
|
|
|
|
last_engines_count = idcount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < idcount; i++) {
|
|
|
|
for (i = 0; i < idcount; i++) {
|
|
|
|
uint8 engine = buf[3 + i] + _vehshifts[feature];
|
|
|
|
uint8 engine = buf[3 + i] + _vehshifts[feature];
|
|
|
|
byte *bp = &buf[4 + idcount];
|
|
|
|
byte *bp = &buf[4 + idcount];
|
|
|
|
|
|
|
|
|
|
|
|
for (c = 0; c < cidcount; c++) {
|
|
|
|
for (c = 0; c < cidcount; c++) {
|
|
|
|
uint8 ctype = grf_load_byte(&bp);
|
|
|
|
uint8 ctype = grf_load_byte(&bp);
|
|
|
|
uint16 supersetid = grf_load_word(&bp);
|
|
|
|
uint16 supersetid = grf_load_word(&bp);
|
|
|
|
|
|
|
|
|
|
|
|
if (supersetid >= _spritesset_count) {
|
|
|
|
if (supersetid >= _spritesset_count) {
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count);
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ctype == 0xff)
|
|
|
|
if (ctype == 0xff)
|
|
|
|
ctype = CID_PURCHASE;
|
|
|
|
ctype = CID_PURCHASE;
|
|
|
|
|
|
|
|
|
|
|
|
if (wagover) {
|
|
|
|
if (wagover) {
|
|
|
|
// TODO: No multiple cargo types per vehicle yet. --pasky
|
|
|
|
// TODO: No multiple cargo types per vehicle yet. --pasky
|
|
|
|
SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count);
|
|
|
|
SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
SetCustomEngineSprites(engine, ctype, &_spritesset[supersetid]);
|
|
|
|
SetCustomEngineSprites(engine, ctype, &_spritesset[supersetid]);
|
|
|
|
last_engines[i] = engine;
|
|
|
|
last_engines[i] = engine;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
byte *bp = buf + 4 + idcount + cidcount * 3;
|
|
|
|
byte *bp = buf + 4 + idcount + cidcount * 3;
|
|
|
|
uint16 supersetid = grf_load_word(&bp);
|
|
|
|
uint16 supersetid = grf_load_word(&bp);
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < idcount; i++) {
|
|
|
|
for (i = 0; i < idcount; i++) {
|
|
|
|
uint8 engine = buf[3 + i] + _vehshifts[feature];
|
|
|
|
uint8 engine = buf[3 + i] + _vehshifts[feature];
|
|
|
|
|
|
|
|
|
|
|
|
// Don't tell me you don't love duplicated code!
|
|
|
|
// Don't tell me you don't love duplicated code!
|
|
|
|
if (supersetid >= _spritesset_count) {
|
|
|
|
if (supersetid >= _spritesset_count) {
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count);
|
|
|
|
grfmsg(GMS_WARN, "VehicleMapSpriteSuperset: Spriteset %x out of range %x, skipping.", supersetid, _spritesset_count);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (wagover) {
|
|
|
|
if (wagover) {
|
|
|
|
// TODO: No multiple cargo types per vehicle yet. --pasky
|
|
|
|
// TODO: No multiple cargo types per vehicle yet. --pasky
|
|
|
|
SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count);
|
|
|
|
SetWagonOverrideSprites(engine, &_spritesset[supersetid], last_engines, last_engines_count);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
SetCustomEngineSprites(engine, CID_DEFAULT, &_spritesset[supersetid]);
|
|
|
|
SetCustomEngineSprites(engine, CID_DEFAULT, &_spritesset[supersetid]);
|
|
|
|
last_engines[i] = engine;
|
|
|
|
last_engines[i] = engine;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -822,30 +841,34 @@ static void VehicleNewName(byte *buf, int len)
|
|
|
|
* factory names etc). We should then also support all languages (by
|
|
|
|
* factory names etc). We should then also support all languages (by
|
|
|
|
* name), not only the original four ones. --pasky */
|
|
|
|
* name), not only the original four ones. --pasky */
|
|
|
|
|
|
|
|
|
|
|
|
if (len > 5) {
|
|
|
|
uint8 feature;
|
|
|
|
uint8 feature = buf[1];
|
|
|
|
uint8 lang;
|
|
|
|
uint8 lang = buf[2];
|
|
|
|
uint8 id;
|
|
|
|
uint8 id = buf[4] + _vehshifts[feature];
|
|
|
|
uint8 endid;
|
|
|
|
uint8 endid = id + buf[3];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (lang & 0x80) {
|
|
|
|
check_length(len, 6, "VehicleNewName");
|
|
|
|
grfmsg(GMS_WARN, "VehicleNewName: No support for changing in-game texts. Skipping.");
|
|
|
|
feature = buf[1];
|
|
|
|
return;
|
|
|
|
lang = buf[2];
|
|
|
|
}
|
|
|
|
id = buf[4] + _vehshifts[feature];
|
|
|
|
|
|
|
|
endid = id + buf[3];
|
|
|
|
|
|
|
|
|
|
|
|
if (!(lang & 3)) {
|
|
|
|
if (lang & 0x80) {
|
|
|
|
/* XXX: If non-English name, silently skip it. */
|
|
|
|
grfmsg(GMS_WARN, "VehicleNewName: No support for changing in-game texts. Skipping.");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
buf += 5, len -= 5;
|
|
|
|
if (!(lang & 3)) {
|
|
|
|
for (; id < endid && len > 0; id++) {
|
|
|
|
/* XXX: If non-English name, silently skip it. */
|
|
|
|
int ofs = strlen(buf) + 1;
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ofs < 128)
|
|
|
|
buf += 5, len -= 5;
|
|
|
|
SetCustomEngineName(id, buf);
|
|
|
|
for (; id < endid && len > 0; id++) {
|
|
|
|
buf += ofs, len -= ofs;
|
|
|
|
int ofs = strlen(buf) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ofs < 128)
|
|
|
|
|
|
|
|
SetCustomEngineName(id, buf);
|
|
|
|
|
|
|
|
buf += ofs, len -= ofs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -862,9 +885,7 @@ static void GraphicsNew(byte *buf, int len)
|
|
|
|
uint8 type;
|
|
|
|
uint8 type;
|
|
|
|
uint8 num;
|
|
|
|
uint8 num;
|
|
|
|
|
|
|
|
|
|
|
|
if (len != 2)
|
|
|
|
check_length(len, 2, "GraphicsNew");
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type = buf[0];
|
|
|
|
type = buf[0];
|
|
|
|
num = buf[1];
|
|
|
|
num = buf[1];
|
|
|
|
|
|
|
|
|
|
|
@ -902,41 +923,44 @@ static void SkipIf(byte *buf, int len)
|
|
|
|
* B num-sprites */
|
|
|
|
* B num-sprites */
|
|
|
|
/* TODO: We only support few tests. */
|
|
|
|
/* TODO: We only support few tests. */
|
|
|
|
/* TODO: More params. More condition types. */
|
|
|
|
/* TODO: More params. More condition types. */
|
|
|
|
|
|
|
|
uint8 param;
|
|
|
|
|
|
|
|
uint8 paramsize;
|
|
|
|
|
|
|
|
uint8 condtype;
|
|
|
|
|
|
|
|
uint8 numsprites;
|
|
|
|
|
|
|
|
int val, result;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
check_length(len, 6, "SkipIf");
|
|
|
|
|
|
|
|
param = buf[1];
|
|
|
|
|
|
|
|
paramsize = buf[2];
|
|
|
|
|
|
|
|
condtype = buf[3];
|
|
|
|
|
|
|
|
numsprites = buf[4 + paramsize];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (param == 0x83) {
|
|
|
|
|
|
|
|
val = _opt.landscape;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "Unsupported param %x. Ignoring test.", param);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (len > 5) {
|
|
|
|
switch (condtype) {
|
|
|
|
uint8 param = buf[1];
|
|
|
|
case 2: result = (buf[4] == val);
|
|
|
|
uint8 paramsize = buf[2];
|
|
|
|
break;
|
|
|
|
uint8 condtype = buf[3];
|
|
|
|
case 3: result = (buf[4] != val);
|
|
|
|
uint8 numsprites = buf[4 + paramsize];
|
|
|
|
break;
|
|
|
|
int val, result;
|
|
|
|
default:
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "Unsupported test %d. Ignoring.", condtype);
|
|
|
|
if (param == 0x83) {
|
|
|
|
|
|
|
|
val = _opt.landscape;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "Unsupported param %x. Ignoring test.", param);
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (condtype) {
|
|
|
|
|
|
|
|
case 2: result = (buf[4] == val);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: result = (buf[4] != val);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
grfmsg(GMS_WARN, "Unsupported test %d. Ignoring.", condtype);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
if (!result)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
_skip_sprites = numsprites;
|
|
|
|
_skip_sprites = numsprites;
|
|
|
|
if (_skip_sprites == 0) {
|
|
|
|
if (_skip_sprites == 0) {
|
|
|
|
/* Zero means there are no sprites to skip, so
|
|
|
|
/* Zero means there are no sprites to skip, so
|
|
|
|
* we use -1 to indicate that all further
|
|
|
|
* we use -1 to indicate that all further
|
|
|
|
* sprites should be skipped. */
|
|
|
|
* sprites should be skipped. */
|
|
|
|
_skip_sprites = -1;
|
|
|
|
_skip_sprites = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -949,17 +973,18 @@ static void GRFInfo(byte *buf, int len)
|
|
|
|
* S name name of this .grf set
|
|
|
|
* S name name of this .grf set
|
|
|
|
* S info string describing the set, and e.g. author and copyright */
|
|
|
|
* S info string describing the set, and e.g. author and copyright */
|
|
|
|
/* TODO: Check version. (We should have own versioning done somehow.) */
|
|
|
|
/* TODO: Check version. (We should have own versioning done somehow.) */
|
|
|
|
|
|
|
|
uint8 version;
|
|
|
|
if (len > 8) {
|
|
|
|
uint32 grfid; /* this is de facto big endian - grf_load_dword() unsuitable */
|
|
|
|
uint8 version = buf[1];
|
|
|
|
char *name;
|
|
|
|
// this is de facto big endian - grf_load_dword() unsuitable
|
|
|
|
char *info;
|
|
|
|
uint32 grfid = buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5];
|
|
|
|
|
|
|
|
char *name = buf + 6;
|
|
|
|
check_length(len, 9, "GRFInfo");
|
|
|
|
char *info = name + strlen(name) + 1;
|
|
|
|
version = buf[1];
|
|
|
|
|
|
|
|
grfid = buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5];
|
|
|
|
DEBUG(grf, 1) ("[%s] Loaded GRFv%d set %08lx - %s:\n%s\n",
|
|
|
|
name = buf + 6;
|
|
|
|
_cur_grffile, version, grfid, name, info);
|
|
|
|
info = name + strlen(name) + 1;
|
|
|
|
}
|
|
|
|
DEBUG(grf, 1) ("[%s] Loaded GRFv%d set %08lx - %s:\n%s\n",
|
|
|
|
|
|
|
|
_cur_grffile, version, grfid, name, info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void SpriteReplace(byte *buf, int len)
|
|
|
|
static void SpriteReplace(byte *buf, int len)
|
|
|
@ -998,16 +1023,17 @@ static void GRFError(byte *buf, int len)
|
|
|
|
"Designed to be used with %s.",
|
|
|
|
"Designed to be used with %s.",
|
|
|
|
"Invalid parameter %s.",
|
|
|
|
"Invalid parameter %s.",
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
uint8 severity;
|
|
|
|
|
|
|
|
uint8 msgid;
|
|
|
|
|
|
|
|
|
|
|
|
if (len > 5) {
|
|
|
|
check_length(len, 6, "GRFError");
|
|
|
|
uint8 severity = buf[1];
|
|
|
|
severity = buf[1];
|
|
|
|
uint8 msgid = buf[3];
|
|
|
|
msgid = buf[3];
|
|
|
|
|
|
|
|
|
|
|
|
if (msgid == 0xff) {
|
|
|
|
if (msgid == 0xff) {
|
|
|
|
grfmsg(severity, "%s", buf+4);
|
|
|
|
grfmsg(severity, "%s", buf+4);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
grfmsg(severity, msgstr[msgid], buf+4);
|
|
|
|
grfmsg(severity, msgstr[msgid], buf+4);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|