diff options
-rw-r--r-- | grfspecial.c | 52 | ||||
-rw-r--r-- | rail_cmd.c | 26 | ||||
-rw-r--r-- | station.h | 8 | ||||
-rw-r--r-- | station_cmd.c | 25 |
4 files changed, 79 insertions, 32 deletions
diff --git a/grfspecial.c b/grfspecial.c index 062f55a94..687149a88 100644 --- a/grfspecial.c +++ b/grfspecial.c @@ -934,7 +934,7 @@ static void VehicleChangeInfo(byte *buf, int len) while (numprops-- && buf < bufend) { uint8 prop = grf_load_byte(&buf); - if (feature == 4) + if (feature == GSF_STATION) // stations don't share those common properties goto run_handler; @@ -1193,15 +1193,33 @@ static void NewVehicle_SpriteGroupMapping(byte *buf, int len) if (feature == GSF_STATION) { // We do things differently for stations. - /* XXX: Currently we don't support cargo-specific images, so - * we go straight to the defaults. */ - byte *bp = buf + 4 + idcount + cidcount * 3; - uint16 groupid = grf_load_word(&bp); - for (i = 0; i < idcount; i++) { - struct StationSpec *stat; uint8 stid = buf[3 + i]; - int j; + StationSpec *stat = &_cur_grffile->stations[stid]; + byte *bp = &buf[4 + idcount]; + + for (c = 0; c < cidcount; c++) { + uint8 ctype = grf_load_byte(&bp); + uint16 groupid = grf_load_word(&bp); + + if (groupid >= _cur_grffile->spritegroups_count) { + grfmsg(GMS_WARN, "VehicleMapSpriteGroup: Spriteset %x out of range %x, skipping.", + groupid, _cur_grffile->spritegroups_count); + return; + } + + if (ctype != 0xFF) { + /* TODO: No support for any other cargo. */ + continue; + } + + stat->relocation[1] = _cur_grffile->spritegroups[groupid]; + } + } + + { + byte *bp = buf + 4 + idcount + cidcount * 3; + uint16 groupid = grf_load_word(&bp); if (groupid >= _cur_grffile->spritegroups_count) { grfmsg(GMS_WARN, "VehicleMapSpriteGroup: Spriteset %x out of range %x, skipping.", @@ -1209,19 +1227,15 @@ static void NewVehicle_SpriteGroupMapping(byte *buf, int len) return; } - stat = &_cur_grffile->stations[stid]; - - // relocate sprite indexes based on spriteset locations - for (j = 0; j < stat->tiles; j++) { - DrawTileSeqStruct *seq; + for (i = 0; i < idcount; i++) { + uint8 stid = buf[3 + i]; + struct StationSpec *stat = &_cur_grffile->stations[stid]; - foreach_draw_tile_seq(seq, (DrawTileSeqStruct*) stat->renderdata[j].seq) { - seq->image += _cur_grffile->spritegroups[groupid].loading[0]; - } + stat->relocation[0] = _cur_grffile->spritegroups[groupid]; + stat->grfid = _cur_grffile->grfid; + SetCustomStation(stid, stat); + stat->classid = 0; } - stat->grfid = _cur_grffile->grfid; - SetCustomStation(stid, stat); - stat->classid = 0; } return; } diff --git a/rail_cmd.c b/rail_cmd.c index 12bca7fb4..87f6aead2 100644 --- a/rail_cmd.c +++ b/rail_cmd.c @@ -1544,19 +1544,21 @@ static void DrawTile_Track(TileInfo *ti) if (!IS_RAIL_DEPOT(m5) && IS_RAIL_WAYPOINT(m5) && _map3_lo[ti->tile]&16) { // look for customization - DrawTileSprites *cust = GetCustomStationRenderdata('WAYP', _map3_hi[ti->tile]); + struct StationSpec *stat = GetCustomStation('WAYP', _map3_hi[ti->tile]); - if (cust) { + if (stat) { DrawTileSeqStruct const *seq; - - cust = &cust[2 + (m5 & 0x1)]; // emulate station tile - open with building + // emulate station tile - open with building + DrawTileSprites *cust = &stat->renderdata[2 + (m5 & 0x1)]; + uint32 relocation = GetCustomStationRelocation(stat, 0); image = cust->ground_sprite; if (image & 0x8000) image = (image & 0x7FFF) + tracktype_offs; DrawGroundSprite(image); foreach_draw_tile_seq(seq, cust->seq) { - DrawSpecialBuilding(seq->image|0x8000, 0, ti, + uint32 image = seq->image + relocation; + DrawSpecialBuilding(image|0x8000, 0, ti, seq->delta_x, seq->delta_y, seq->delta_z, seq->width, seq->height, seq->unk); } @@ -1622,16 +1624,18 @@ void DrawTrainDepotSprite(int x, int y, int image, int railtype) void DrawWaypointSprite(int x, int y, int stat_id) { - // TODO: We should use supersets with cargo-id FF, if available. --pasky - DrawTileSprites *cust = GetCustomStationRenderdata('WAYP', stat_id); + struct StationSpec *stat = GetCustomStation('WAYP', stat_id); + uint32 relocation; + DrawTileSprites *cust; DrawTileSeqStruct const *seq; uint32 ormod, img; - assert(cust); + assert(stat); + relocation = GetCustomStationRelocation(stat, 1); // emulate station tile - open with building // add 1 to get the other direction - cust = &cust[2]; + cust = &stat->renderdata[2]; ormod = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(_local_player)); @@ -1644,7 +1648,9 @@ void DrawWaypointSprite(int x, int y, int stat_id) foreach_draw_tile_seq(seq, cust->seq) { Point pt = RemapCoords(seq->delta_x, seq->delta_y, seq->delta_z); - DrawSprite((seq->image&0x3FFF) | ormod, x + pt.x, y + pt.y); + uint32 image = seq->image + relocation; + + DrawSprite((image&0x3FFF) | ormod, x + pt.x, y + pt.y); } } @@ -1,6 +1,7 @@ #ifndef STATION_H #define STATION_H +#include "engine.h" #include "vehicle.h" typedef struct GoodsEntry { @@ -117,6 +118,10 @@ struct StationSpec { byte tiles; DrawTileSprites renderdata[8]; + + /* Sprite offsets for renderdata->seq->image. relocation[0] is default + * whilst relocation[1] is "CID_PURCHASE". */ + struct SpriteGroup relocation[2]; }; /* Here, @stid is local per-GRFFile station index. If spec->localidx is not yet @@ -126,7 +131,8 @@ struct StationSpec { void SetCustomStation(byte stid, struct StationSpec *spec); /* Here, @stid is global station index (in continous range 0..GetCustomStationsCount()) * (lookup is therefore very fast as we do this very frequently). */ -DrawTileSprites *GetCustomStationRenderdata(uint32 classid, byte stid); +struct StationSpec *GetCustomStation(uint32 classid, byte stid); +uint32 GetCustomStationRelocation(struct StationSpec *spec, byte ctype); int GetCustomStationsCount(uint32 classid); #endif /* STATION_H */ diff --git a/station_cmd.c b/station_cmd.c index 8d8ce56ea..a0f1460d4 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -994,12 +994,33 @@ void SetCustomStation(byte local_stid, struct StationSpec *spec) memcpy(&_waypoint_data[stid], spec, sizeof(*spec)); } -DrawTileSprites *GetCustomStationRenderdata(uint32 classid, byte stid) +struct StationSpec *GetCustomStation(uint32 classid, byte stid) { assert(classid == 'WAYP'); if (stid > _waypoint_highest_id) return NULL; - return _waypoint_data[stid].renderdata; + return &_waypoint_data[stid]; +} + +uint32 GetCustomStationRelocation(struct StationSpec *spec, byte ctype) +{ + assert(spec->classid == 'WAYP'); + + /* In the future, variational spritegroups will kick in through this + * accessor. */ + + if (spec->relocation[ctype].loading_count != 0) { + return spec->relocation[ctype].loading[0]; + } else if (spec->relocation[ctype].loading_count != 0) { + return spec->relocation[ctype].loaded[0]; + } else { + error("Custom station 0x%08x::0x%02x has no sprites associated.", + spec->grfid, spec->localidx); + /* This is what gets subscribed of dtss->image in grfspecial.c, + * so it's probably kinda "default offset". Try to use it as + * emergency measure. */ + return 0x42D; + } } int GetCustomStationsCount(uint32 classid) |