(svn r9416) -Codechange: Split NewGRF Action 3 handler into separate functions for each feature (vehicles are common, though)

This commit is contained in:
peter1138 2007-03-23 20:01:25 +00:00
parent c603a27d29
commit 2e32df30dd
1 changed files with 150 additions and 135 deletions

View File

@ -2394,149 +2394,27 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype)
return ctype;
}
/* Action 0x03 */
static void FeatureMapSpriteGroup(byte *buf, int len)
{
/* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
* id-list := [<id>] [id-list]
* cargo-list := <cargo-type> <cid> [cargo-list]
*
* B feature see action 0
* B n-id bits 0-6: how many IDs this definition applies to
* bit 7: if set, this is a wagon override definition (see below)
* B ids the IDs for which this definition applies
* B num-cid number of cargo IDs (sprite group IDs) in this definition
* can be zero, in that case the def-cid is used always
* B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
* W cid cargo ID (sprite group ID) for this type of cargo
* W def-cid default cargo ID (sprite group ID) */
/* TODO: Bridges, town houses. */
/* TODO: Multiple cargo support could be useful even for trains/cars -
* cargo id 0xff is used for showing images in the build train list. */
static void VehicleMapSpriteGroup(byte *buf, byte feature, uint8 idcount, uint8 cidcount, bool wagover)
{
static byte *last_engines;
static int last_engines_count;
if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
uint8 feature = buf[1];
uint8 idcount = buf[2] & 0x7F;
bool wagover = (buf[2] & 0x80) == 0x80;
if (!check_length(len, 3 + idcount, "FeatureMapSpriteGroup")) return;
/* If idcount is zero, this is a feature callback */
if (idcount == 0) {
grfmsg(2, "FeatureMapSpriteGroup: Feature callbacks not implemented yet");
return;
}
uint8 cidcount = buf[3 + idcount];
if (!check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup")) return;
grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
feature, idcount, cidcount, wagover);
if (feature > GSF_STATION && feature != GSF_TOWNHOUSE) {
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
return;
}
if (feature == GSF_STATION) {
/* We do things differently for stations. */
for (uint i = 0; i < idcount; i++) {
uint8 stid = buf[3 + i];
StationSpec *statspec = _cur_grffile->stations[stid];
byte *bp = &buf[4 + idcount];
for (uint c = 0; c < cidcount; c++) {
uint8 ctype = grf_load_byte(&bp);
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
groupid, _cur_grffile->spritegroups_count);
return;
}
ctype = TranslateCargo(feature, ctype);
if (ctype == CT_INVALID) continue;
statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
}
if (!wagover) {
if (last_engines_count != idcount) {
last_engines = ReallocT(last_engines, idcount);
last_engines_count = idcount;
}
{
byte *bp = buf + 4 + idcount + cidcount * 3;
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
groupid, _cur_grffile->spritegroups_count);
return;
}
for (uint i = 0; i < idcount; i++) {
uint8 stid = buf[3 + i];
StationSpec *statspec = _cur_grffile->stations[stid];
statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
statspec->grfid = _cur_grffile->grfid;
statspec->localidx = stid;
SetCustomStationSpec(statspec);
}
}
return;
} else if (feature == GSF_TOWNHOUSE) {
byte *bp = &buf[4 + idcount + cidcount * 3];
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
groupid, _cur_grffile->spritegroups_count);
return;
}
for (uint i = 0; i < idcount; i++) {
uint8 hid = buf[3 + i];
HouseSpec *hs = _cur_grffile->housespec[hid];
if (hs == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Too many houses defined, skipping");
return;
}
hs->spritegroup = _cur_grffile->spritegroups[groupid];
}
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 (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
return;
}
if (!wagover && last_engines_count != idcount) {
last_engines = ReallocT(last_engines, idcount);
last_engines_count = idcount;
}
if (wagover) {
} else {
if (last_engines_count == 0) {
grfmsg(0, "FeatureMapSpriteGroup: WagonOverride: No engine to do override with");
return;
}
grfmsg(6, "FeatureMapSpriteGroup: WagonOverride: %u engines, %u wagons",
last_engines_count, idcount);
}
for (uint i = 0; i < idcount; i++) {
uint8 engine_id = buf[3 + i];
uint8 engine = engine_id + _vehshifts[feature];
@ -2557,7 +2435,7 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
return;
continue;
}
ctype = TranslateCargo(feature, ctype);
@ -2573,7 +2451,7 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
}
{
byte *bp = buf + 4 + idcount + cidcount * 3;
byte *bp = &buf[4 + idcount + cidcount * 3];
uint16 groupid = grf_load_word(&bp);
grfmsg(8, "-- Default group id 0x%04X", groupid);
@ -2583,13 +2461,14 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
/* Don't tell me you don't love duplicated code! */
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping", groupid, _cur_grffile->spritegroups_count);
return;
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
groupid, _cur_grffile->spritegroups_count);
continue;
}
if (wagover) {
/* If the ID for this action 3 is the same as the vehicle ID,
* this indicates we have a helicopter rotor override. */
* this indicates we have a helicopter rotor override. */
if (feature == GSF_AIRCRAFT && engine == last_engines[i]) {
SetRotorOverrideSprites(engine, _cur_grffile->spritegroups[groupid]);
} else {
@ -2605,6 +2484,142 @@ static void FeatureMapSpriteGroup(byte *buf, int len)
}
}
static void StationMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
{
for (uint i = 0; i < idcount; i++) {
uint8 stid = buf[3 + i];
StationSpec *statspec = _cur_grffile->stations[stid];
byte *bp = &buf[4 + idcount];
for (uint c = 0; c < cidcount; c++) {
uint8 ctype = grf_load_byte(&bp);
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
groupid, _cur_grffile->spritegroups_count);
continue;
}
ctype = TranslateCargo(GSF_STATION, ctype);
if (ctype == CT_INVALID) continue;
statspec->spritegroup[ctype] = _cur_grffile->spritegroups[groupid];
}
}
{
byte *bp = &buf[4 + idcount + cidcount * 3];
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping",
groupid, _cur_grffile->spritegroups_count);
return;
}
for (uint i = 0; i < idcount; i++) {
uint8 stid = buf[3 + i];
StationSpec *statspec = _cur_grffile->stations[stid];
statspec->spritegroup[CT_DEFAULT] = _cur_grffile->spritegroups[groupid];
statspec->grfid = _cur_grffile->grfid;
statspec->localidx = stid;
SetCustomStationSpec(statspec);
}
}
}
static void TownHouseMapSpriteGroup(byte *buf, uint8 idcount, uint8 cidcount)
{
byte *bp = &buf[4 + idcount + cidcount * 3];
uint16 groupid = grf_load_word(&bp);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Spriteset 0x%04X out of range 0x%X or empty, skipping.",
groupid, _cur_grffile->spritegroups_count);
return;
}
for (uint i = 0; i < idcount; i++) {
uint8 hid = buf[3 + i];
HouseSpec *hs = _cur_grffile->housespec[hid];
if (hs == NULL) {
grfmsg(1, "FeatureMapSpriteGroup: Too many houses defined, skipping");
return;
}
hs->spritegroup = _cur_grffile->spritegroups[groupid];
}
}
/* Action 0x03 */
static void FeatureMapSpriteGroup(byte *buf, int len)
{
/* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
* id-list := [<id>] [id-list]
* cargo-list := <cargo-type> <cid> [cargo-list]
*
* B feature see action 0
* B n-id bits 0-6: how many IDs this definition applies to
* bit 7: if set, this is a wagon override definition (see below)
* B ids the IDs for which this definition applies
* B num-cid number of cargo IDs (sprite group IDs) in this definition
* can be zero, in that case the def-cid is used always
* B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
* W cid cargo ID (sprite group ID) for this type of cargo
* W def-cid default cargo ID (sprite group ID) */
if (!check_length(len, 6, "FeatureMapSpriteGroup")) return;
uint8 feature = buf[1];
uint8 idcount = buf[2] & 0x7F;
bool wagover = (buf[2] & 0x80) == 0x80;
if (!check_length(len, 3 + idcount, "FeatureMapSpriteGroup")) return;
/* If idcount is zero, this is a feature callback */
if (idcount == 0) {
grfmsg(2, "FeatureMapSpriteGroup: Feature callbacks not implemented yet");
return;
}
uint8 cidcount = buf[3 + idcount];
if (!check_length(len, 4 + idcount + cidcount * 3, "FeatureMapSpriteGroup")) return;
grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids, %d cids, wagon override %d",
feature, idcount, cidcount, wagover);
if (_cur_grffile->spriteset_start == 0 || _cur_grffile->spritegroups == 0) {
grfmsg(1, "FeatureMapSpriteGroup: No sprite set to work on! Skipping");
return;
}
switch (feature) {
case GSF_TRAIN:
case GSF_ROAD:
case GSF_SHIP:
case GSF_AIRCRAFT:
VehicleMapSpriteGroup(buf, feature, idcount, cidcount, wagover);
return;
case GSF_STATION:
StationMapSpriteGroup(buf, idcount, cidcount);
return;
case GSF_TOWNHOUSE:
TownHouseMapSpriteGroup(buf, idcount, cidcount);
return;
default:
grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
return;
}
}
/* Action 0x04 */
static void FeatureNewName(byte *buf, int len)
{