summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2016-10-16 14:57:56 +0000
committerfrosch <frosch@openttd.org>2016-10-16 14:57:56 +0000
commitd2393b4f6c89b75a90452fe68ab8a1cfbd8c353f (patch)
treec7934b2d2a19fa55c53ac063b91cc519fb4b753a
parentf5409c713b002012c6a2218de1720a91282eab67 (diff)
downloadopenttd-d2393b4f6c89b75a90452fe68ab8a1cfbd8c353f.tar.xz
(svn r27666) -Codechange: Pass vehicle sprites around using a struct VehicleSpriteSeq.
-rw-r--r--src/aircraft.h4
-rw-r--r--src/aircraft_cmd.cpp69
-rw-r--r--src/aircraft_gui.cpp15
-rw-r--r--src/articulated_vehicles.cpp2
-rw-r--r--src/disaster_vehicle.cpp5
-rw-r--r--src/effectvehicle.cpp37
-rw-r--r--src/newgrf_engine.cpp19
-rw-r--r--src/newgrf_engine.h16
-rw-r--r--src/roadveh.h2
-rw-r--r--src/roadveh_cmd.cpp34
-rw-r--r--src/roadveh_gui.cpp4
-rw-r--r--src/saveload/oldloader_sl.cpp6
-rw-r--r--src/saveload/vehicle_sl.cpp14
-rw-r--r--src/ship.h2
-rw-r--r--src/ship_cmd.cpp31
-rw-r--r--src/ship_gui.cpp8
-rw-r--r--src/train.h2
-rw-r--r--src/train_cmd.cpp59
-rw-r--r--src/train_gui.cpp8
-rw-r--r--src/vehicle.cpp8
-rw-r--r--src/vehicle_base.h54
-rw-r--r--src/vehicle_gui.cpp9
22 files changed, 248 insertions, 160 deletions
diff --git a/src/aircraft.h b/src/aircraft.h
index 0805ae8ec..f0ca1c4ab 100644
--- a/src/aircraft.h
+++ b/src/aircraft.h
@@ -93,7 +93,7 @@ struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
void UpdateDeltaXY(Direction direction);
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_AIRCRAFT_INC : EXPENSES_AIRCRAFT_RUN; }
bool IsPrimaryVehicle() const { return this->IsNormalAircraft(); }
- SpriteID GetImage(Direction direction, EngineImageType image_type) const;
+ void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->cur_speed; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
int GetSpeedOldUnits() const { return this->vcache.cached_max_speed * 10 / 128; }
@@ -141,7 +141,7 @@ struct Aircraft FINAL : public SpecializedVehicle<Aircraft, VEH_AIRCRAFT> {
*/
#define FOR_ALL_AIRCRAFT(var) FOR_ALL_VEHICLES_OF_TYPE(Aircraft, var)
-SpriteID GetRotorImage(const Aircraft *v, EngineImageType image_type);
+void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteSeq *result);
Station *GetTargetAirportIfValid(const Aircraft *v);
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index edb10af32..c7cb5bbb2 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -152,64 +152,67 @@ static StationID FindNearestHangar(const Aircraft *v)
return index;
}
-SpriteID Aircraft::GetImage(Direction direction, EngineImageType image_type) const
+void Aircraft::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
{
uint8 spritenum = this->spritenum;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleSprite(this, direction, image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleSprite(this, direction, image_type, result);
+ if (result->IsValid()) return;
spritenum = this->GetEngine()->original_image_index;
}
assert(IsValidImageIndex<VEH_AIRCRAFT>(spritenum));
- return direction + _aircraft_sprite[spritenum];
+ result->Set(direction + _aircraft_sprite[spritenum]);
}
-SpriteID GetRotorImage(const Aircraft *v, EngineImageType image_type)
+void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteSeq *result)
{
assert(v->subtype == AIR_HELICOPTER);
const Aircraft *w = v->Next()->Next();
if (is_custom_sprite(v->spritenum)) {
- SpriteID sprite = GetCustomRotorSprite(v, false, image_type);
- if (sprite != 0) return sprite;
+ GetCustomRotorSprite(v, false, image_type, result);
+ if (result->IsValid()) return;
}
/* Return standard rotor sprites if there are no custom sprites for this helicopter */
- return SPR_ROTOR_STOPPED + w->state;
+ result->Set(SPR_ROTOR_STOPPED + w->state);
}
-static SpriteID GetAircraftIcon(EngineID engine, EngineImageType image_type)
+static void GetAircraftIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
{
const Engine *e = Engine::Get(engine);
uint8 spritenum = e->u.air.image_index;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W, image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleIcon(engine, DIR_W, image_type, result);
+ if (result->IsValid()) return;
spritenum = e->original_image_index;
}
assert(IsValidImageIndex<VEH_AIRCRAFT>(spritenum));
- return DIR_W + _aircraft_sprite[spritenum];
+ result->Set(DIR_W + _aircraft_sprite[spritenum]);
}
void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
{
- SpriteID sprite = GetAircraftIcon(engine, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetAircraftIcon(engine, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
preferred_x = Clamp(preferred_x,
left - UnScaleGUI(real_sprite->x_offs),
right - UnScaleGUI(real_sprite->width) - UnScaleGUI(real_sprite->x_offs));
- DrawSprite(sprite, pal, preferred_x, y);
+ DrawSprite(seq.sprite, pal, preferred_x, y);
if (!(AircraftVehInfo(engine)->subtype & AIR_CTOL)) {
- SpriteID rotor_sprite = GetCustomRotorIcon(engine, image_type);
- if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
- DrawSprite(rotor_sprite, PAL_NONE, preferred_x, y - ScaleGUITrad(5));
+ VehicleSpriteSeq rotor_seq;
+ GetCustomRotorIcon(engine, image_type, &rotor_seq);
+ if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
+ DrawSprite(rotor_seq.sprite, PAL_NONE, preferred_x, y - ScaleGUITrad(5));
}
}
@@ -224,7 +227,10 @@ void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID en
*/
void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
{
- const Sprite *spr = GetSprite(GetAircraftIcon(engine, image_type), ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetAircraftIcon(engine, image_type, &seq);
+
+ const Sprite *spr = GetSprite(seq.sprite, ST_NORMAL);
width = UnScaleGUI(spr->width);
height = UnScaleGUI(spr->height);
@@ -317,7 +323,8 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
v->date_of_last_service = _date;
v->build_year = u->build_year = _cur_year;
- v->cur_image = u->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
+ u->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
u->random_bits = VehicleRandomBits();
@@ -349,7 +356,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
w->vehstatus = VS_HIDDEN | VS_UNCLICKABLE;
w->spritenum = 0xFF;
w->subtype = AIR_ROTOR;
- w->cur_image = SPR_ROTOR_STOPPED;
+ w->sprite_seq.Set(SPR_ROTOR_STOPPED);
w->random_bits = VehicleRandomBits();
/* Use rotor's air.state to store the rotor animation frame */
w->state = HRS_ROTOR_STOPPED;
@@ -468,21 +475,21 @@ static void HelicopterTickHandler(Aircraft *v)
int tick = ++u->tick_counter;
int spd = u->cur_speed >> 4;
- SpriteID img;
+ VehicleSpriteSeq seq;
if (spd == 0) {
u->state = HRS_ROTOR_STOPPED;
- img = GetRotorImage(v, EIT_ON_MAP);
- if (u->cur_image == img) return;
+ GetRotorImage(v, EIT_ON_MAP, &seq);
+ if (u->sprite_seq == seq) return;
} else if (tick >= spd) {
u->tick_counter = 0;
u->state++;
if (u->state > HRS_ROTOR_MOVING_3) u->state = HRS_ROTOR_MOVING_1;
- img = GetRotorImage(v, EIT_ON_MAP);
+ GetRotorImage(v, EIT_ON_MAP, &seq);
} else {
return;
}
- u->cur_image = img;
+ u->sprite_seq = seq;
u->UpdatePositionAndViewport();
}
@@ -502,7 +509,9 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
v->UpdatePosition();
v->UpdateViewport(true, false);
- if (v->subtype == AIR_HELICOPTER) v->Next()->Next()->cur_image = GetRotorImage(v, EIT_ON_MAP);
+ if (v->subtype == AIR_HELICOPTER) {
+ GetRotorImage(v, EIT_ON_MAP, &v->Next()->Next()->sprite_seq);
+ }
Aircraft *u = v->Next();
@@ -513,7 +522,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
u->z_pos = GetSlopePixelZ(safe_x, safe_y);
- u->cur_image = v->cur_image;
+ u->sprite_seq.sprite = v->sprite_seq.sprite;
u->UpdatePositionAndViewport();
@@ -1237,7 +1246,9 @@ void Aircraft::MarkDirty()
{
this->colourmap = PAL_NONE;
this->UpdateViewport(true, false);
- if (this->subtype == AIR_HELICOPTER) this->Next()->Next()->cur_image = GetRotorImage(this, EIT_ON_MAP);
+ if (this->subtype == AIR_HELICOPTER) {
+ GetRotorImage(this, EIT_ON_MAP, &this->Next()->Next()->sprite_seq);
+ }
}
diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp
index c3379d395..752e0da90 100644
--- a/src/aircraft_gui.cpp
+++ b/src/aircraft_gui.cpp
@@ -83,8 +83,10 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
{
bool rtl = _current_text_dir == TD_RTL;
- SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
int width = UnScaleGUI(real_sprite->width);
int x_offs = UnScaleGUI(real_sprite->x_offs);
@@ -95,13 +97,14 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
int heli_offs = 0;
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
- DrawSprite(sprite, pal, x, y + y_offs);
+ DrawSprite(seq.sprite, pal, x, y + y_offs);
if (helicopter) {
const Aircraft *a = Aircraft::From(v);
- SpriteID rotor_sprite = GetCustomRotorSprite(a, true, image_type);
- if (rotor_sprite == 0) rotor_sprite = SPR_ROTOR_STOPPED;
+ VehicleSpriteSeq rotor_seq;
+ GetCustomRotorSprite(a, true, image_type, &rotor_seq);
+ if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
heli_offs = ScaleGUITrad(5);
- DrawSprite(rotor_sprite, PAL_NONE, x, y + y_offs - heli_offs);
+ DrawSprite(rotor_seq.sprite, PAL_NONE, x, y + y_offs - heli_offs);
}
if (v->index == selection) {
x += x_offs;
diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp
index 8c372e7ea..04c9f95a9 100644
--- a/src/articulated_vehicles.cpp
+++ b/src/articulated_vehicles.cpp
@@ -441,7 +441,7 @@ void AddArticulatedParts(Vehicle *first)
v->max_age = 0;
v->engine_type = engine_type;
v->value = 0;
- v->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
if (flip_image) v->spritenum++;
diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp
index d75e2d460..65a9187e3 100644
--- a/src/disaster_vehicle.cpp
+++ b/src/disaster_vehicle.cpp
@@ -112,7 +112,7 @@ void DisasterVehicle::UpdateImage()
{
SpriteID img = this->image_override;
if (img == 0) img = _disaster_images[this->subtype][this->direction];
- this->cur_image = img;
+ this->sprite_seq.Set(img);
}
/**
@@ -499,7 +499,8 @@ static bool DisasterTick_Helicopter_Rotors(DisasterVehicle *v)
v->tick_counter++;
if (HasBit(v->tick_counter, 0)) return true;
- if (++v->cur_image > SPR_ROTOR_MOVING_3) v->cur_image = SPR_ROTOR_MOVING_1;
+ SpriteID &cur_image = v->sprite_seq.sprite;
+ if (++cur_image > SPR_ROTOR_MOVING_3) cur_image = SPR_ROTOR_MOVING_1;
v->UpdatePositionAndViewport();
diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp
index c871ac09a..266a8e096 100644
--- a/src/effectvehicle.cpp
+++ b/src/effectvehicle.cpp
@@ -30,8 +30,8 @@
*/
static bool IncrementSprite(EffectVehicle *v, SpriteID last)
{
- if (v->cur_image != last) {
- v->cur_image++;
+ if (v->sprite_seq.sprite != last) {
+ v->sprite_seq.sprite++;
return true;
} else {
return false;
@@ -41,7 +41,7 @@ static bool IncrementSprite(EffectVehicle *v, SpriteID last)
static void ChimneySmokeInit(EffectVehicle *v)
{
uint32 r = Random();
- v->cur_image = SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3);
+ v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3));
v->progress = GB(r, 16, 3);
}
@@ -57,7 +57,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
}
if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) {
- v->cur_image = SPR_CHIMNEY_SMOKE_0;
+ v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0);
}
v->progress = 7;
v->UpdatePositionAndViewport();
@@ -68,7 +68,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
static void SteamSmokeInit(EffectVehicle *v)
{
- v->cur_image = SPR_STEAM_SMOKE_0;
+ v->sprite_seq.Set(SPR_STEAM_SMOKE_0);
v->progress = 12;
}
@@ -98,7 +98,7 @@ static bool SteamSmokeTick(EffectVehicle *v)
static void DieselSmokeInit(EffectVehicle *v)
{
- v->cur_image = SPR_DIESEL_SMOKE_0;
+ v->sprite_seq.Set(SPR_DIESEL_SMOKE_0);
v->progress = 0;
}
@@ -122,7 +122,7 @@ static bool DieselSmokeTick(EffectVehicle *v)
static void ElectricSparkInit(EffectVehicle *v)
{
- v->cur_image = SPR_ELECTRIC_SPARK_0;
+ v->sprite_seq.Set(SPR_ELECTRIC_SPARK_0);
v->progress = 1;
}
@@ -145,7 +145,7 @@ static bool ElectricSparkTick(EffectVehicle *v)
static void SmokeInit(EffectVehicle *v)
{
- v->cur_image = SPR_SMOKE_0;
+ v->sprite_seq.Set(SPR_SMOKE_0);
v->progress = 12;
}
@@ -175,7 +175,7 @@ static bool SmokeTick(EffectVehicle *v)
static void ExplosionLargeInit(EffectVehicle *v)
{
- v->cur_image = SPR_EXPLOSION_LARGE_0;
+ v->sprite_seq.Set(SPR_EXPLOSION_LARGE_0);
v->progress = 0;
}
@@ -195,7 +195,7 @@ static bool ExplosionLargeTick(EffectVehicle *v)
static void BreakdownSmokeInit(EffectVehicle *v)
{
- v->cur_image = SPR_BREAKDOWN_SMOKE_0;
+ v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
v->progress = 0;
}
@@ -204,7 +204,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
v->progress++;
if ((v->progress & 7) == 0) {
if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) {
- v->cur_image = SPR_BREAKDOWN_SMOKE_0;
+ v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
}
v->UpdatePositionAndViewport();
}
@@ -220,7 +220,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
static void ExplosionSmallInit(EffectVehicle *v)
{
- v->cur_image = SPR_EXPLOSION_SMALL_0;
+ v->sprite_seq.Set(SPR_EXPLOSION_SMALL_0);
v->progress = 0;
}
@@ -240,7 +240,7 @@ static bool ExplosionSmallTick(EffectVehicle *v)
static void BulldozerInit(EffectVehicle *v)
{
- v->cur_image = SPR_BULLDOZER_NE;
+ v->sprite_seq.Set(SPR_BULLDOZER_NE);
v->progress = 0;
v->animation_state = 0;
v->animation_substate = 0;
@@ -291,7 +291,7 @@ static bool BulldozerTick(EffectVehicle *v)
if ((v->progress & 7) == 0) {
const BulldozerMovement *b = &_bulldozer_movement[v->animation_state];
- v->cur_image = SPR_BULLDOZER_NE + b->image;
+ v->sprite_seq.Set(SPR_BULLDOZER_NE + b->image);
v->x_pos += _inc_by_dir[b->direction].x;
v->y_pos += _inc_by_dir[b->direction].y;
@@ -313,7 +313,7 @@ static bool BulldozerTick(EffectVehicle *v)
static void BubbleInit(EffectVehicle *v)
{
- v->cur_image = SPR_BUBBLE_GENERATE_0;
+ v->sprite_seq.Set(SPR_BUBBLE_GENERATE_0);
v->spritenum = 0;
v->progress = 0;
}
@@ -476,8 +476,9 @@ static bool BubbleTick(EffectVehicle *v)
if ((v->progress & 3) != 0) return true;
if (v->spritenum == 0) {
- v->cur_image++;
- if (v->cur_image < SPR_BUBBLE_GENERATE_3) {
+ SpriteID &cur_image = v->sprite_seq.sprite;
+ cur_image++;
+ if (cur_image < SPR_BUBBLE_GENERATE_3) {
v->UpdatePositionAndViewport();
return true;
}
@@ -522,7 +523,7 @@ static bool BubbleTick(EffectVehicle *v)
v->x_pos += b->x;
v->y_pos += b->y;
v->z_pos += b->z;
- v->cur_image = SPR_BUBBLE_0 + b->image;
+ v->sprite_seq.Set(SPR_BUBBLE_0 + b->image);
v->UpdatePositionAndViewport();
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index 4aafa10f9..ba8367c7d 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -1023,17 +1023,19 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle
-SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type)
+void GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type, VehicleSpriteSeq *result)
{
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_CACHED, false, CBID_NO_CALLBACK, image_type);
+ result->Clear();
+
const SpriteGroup *group = object.Resolve();
- if (group == NULL || group->GetNumResults() == 0) return 0;
+ if (group == NULL || group->GetNumResults() == 0) return;
- return group->GetResult() + (direction % group->GetNumResults());
+ result->Set(group->GetResult() + (direction % group->GetNumResults()));
}
-SpriteID GetRotorOverrideSprite(EngineID engine, const Aircraft *v, bool info_view, EngineImageType image_type)
+void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info_view, EngineImageType image_type, VehicleSpriteSeq *result)
{
const Engine *e = Engine::Get(engine);
@@ -1042,13 +1044,14 @@ SpriteID GetRotorOverrideSprite(EngineID engine, const Aircraft *v, bool info_vi
assert(!(e->u.air.subtype & AIR_CTOL));
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_SELF, info_view, CBID_NO_CALLBACK, image_type);
- const SpriteGroup *group = object.Resolve();
+ result->Clear();
+ uint rotor_pos = v == NULL || info_view ? 0 : v->Next()->Next()->state;
- if (group == NULL || group->GetNumResults() == 0) return 0;
+ const SpriteGroup *group = object.Resolve();
- if (v == NULL || info_view) return group->GetResult();
+ if (group == NULL || group->GetNumResults() == 0) return;
- return group->GetResult() + (v->Next()->Next()->state % group->GetNumResults());
+ result->Set(group->GetResult() + (rotor_pos % group->GetNumResults()));
}
diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h
index 4a6f211c4..3c8108737 100644
--- a/src/newgrf_engine.h
+++ b/src/newgrf_engine.h
@@ -64,13 +64,19 @@ static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29;
static const uint ROADVEHINFO_DEFAULT_VEHICLE_WIDTH = 32;
static const uint VEHICLEINFO_FULL_VEHICLE_WIDTH = 32;
+struct VehicleSpriteSeq;
+
void SetWagonOverrideSprites(EngineID engine, CargoID cargo, const struct SpriteGroup *group, EngineID *train_id, uint trains);
const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, EngineID overriding_engine);
void SetCustomEngineSprites(EngineID engine, byte cargo, const struct SpriteGroup *group);
-SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type);
-SpriteID GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info_view, EngineImageType image_type);
-#define GetCustomRotorSprite(v, i, image_type) GetRotorOverrideSprite(v->engine_type, v, i, image_type)
-#define GetCustomRotorIcon(et, image_type) GetRotorOverrideSprite(et, NULL, true, image_type)
+
+void GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type, VehicleSpriteSeq *result);
+#define GetCustomVehicleSprite(v, direction, image_type, result) GetCustomEngineSprite(v->engine_type, v, direction, image_type, result)
+#define GetCustomVehicleIcon(et, direction, image_type, result) GetCustomEngineSprite(et, NULL, direction, image_type, result)
+
+void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info_view, EngineImageType image_type, VehicleSpriteSeq *result);
+#define GetCustomRotorSprite(v, i, image_type, result) GetRotorOverrideSprite(v->engine_type, v, i, image_type, result)
+#define GetCustomRotorIcon(et, image_type, result) GetRotorOverrideSprite(et, NULL, true, image_type, result)
/* Forward declaration of GRFFile, to avoid unnecessary inclusion of newgrf.h
* elsewhere... */
@@ -81,8 +87,6 @@ void SetEngineGRF(EngineID engine, const struct GRFFile *file);
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v);
uint16 GetVehicleCallbackParent(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent);
bool UsesWagonOverride(const Vehicle *v);
-#define GetCustomVehicleSprite(v, direction, image_type) GetCustomEngineSprite(v->engine_type, v, direction, image_type)
-#define GetCustomVehicleIcon(et, direction, image_type) GetCustomEngineSprite(et, NULL, direction, image_type)
/* Handler to Evaluate callback 36. If the callback fails (i.e. most of the
* time) orig_value is returned */
diff --git a/src/roadveh.h b/src/roadveh.h
index 5b265f047..b1865fc22 100644
--- a/src/roadveh.h
+++ b/src/roadveh.h
@@ -108,7 +108,7 @@ struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
void UpdateDeltaXY(Direction direction);
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_ROADVEH_INC : EXPENSES_ROADVEH_RUN; }
bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
- SpriteID GetImage(Direction direction, EngineImageType image_type) const;
+ void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->gcache.last_speed / 2; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
Money GetRunningCost() const;
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index 35c671d35..e956787b0 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -113,40 +113,39 @@ int RoadVehicle::GetDisplayImageWidth(Point *offset) const
return ScaleGUITrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH);
}
-static SpriteID GetRoadVehIcon(EngineID engine, EngineImageType image_type)
+static void GetRoadVehIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
{
const Engine *e = Engine::Get(engine);
uint8 spritenum = e->u.road.image_index;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W, image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleIcon(engine, DIR_W, image_type, result);
+ if (result->IsValid()) return;
spritenum = e->original_image_index;
}
assert(IsValidImageIndex<VEH_ROAD>(spritenum));
- return DIR_W + _roadveh_images[spritenum];
+ result->Set(DIR_W + _roadveh_images[spritenum]);
}
-SpriteID RoadVehicle::GetImage(Direction direction, EngineImageType image_type) const
+void RoadVehicle::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
{
uint8 spritenum = this->spritenum;
- SpriteID sprite;
if (is_custom_sprite(spritenum)) {
- sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type, result);
+ if (result->IsValid()) return;
spritenum = this->GetEngine()->original_image_index;
}
assert(IsValidImageIndex<VEH_ROAD>(spritenum));
- sprite = direction + _roadveh_images[spritenum];
+ SpriteID sprite = direction + _roadveh_images[spritenum];
if (this->cargo.StoredCount() >= this->cargo_cap / 2U) sprite += _roadveh_full_adder[spritenum];
- return sprite;
+ result->Set(sprite);
}
/**
@@ -160,12 +159,14 @@ SpriteID RoadVehicle::GetImage(Direction direction, EngineImageType image_type)
*/
void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
{
- SpriteID sprite = GetRoadVehIcon(engine, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetRoadVehIcon(engine, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
preferred_x = Clamp(preferred_x,
left - UnScaleGUI(real_sprite->x_offs),
right - UnScaleGUI(real_sprite->width) - UnScaleGUI(real_sprite->x_offs));
- DrawSprite(sprite, pal, preferred_x, y);
+ DrawSprite(seq.sprite, pal, preferred_x, y);
}
/**
@@ -179,7 +180,10 @@ void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID eng
*/
void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
{
- const Sprite *spr = GetSprite(GetRoadVehIcon(engine, image_type), ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetRoadVehIcon(engine, image_type, &seq);
+
+ const Sprite *spr = GetSprite(seq.sprite, ST_NORMAL);
width = UnScaleGUI(spr->width);
height = UnScaleGUI(spr->height);
@@ -306,7 +310,7 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin
v->date_of_last_service = _date;
v->build_year = _cur_year;
- v->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
v->SetFrontEngine();
diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp
index 46ff6cea7..26027a889 100644
--- a/src/roadveh_gui.cpp
+++ b/src/roadveh_gui.cpp
@@ -149,7 +149,9 @@ void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID se
if (rtl ? px + width > 0 : px - width < max_width) {
PaletteID pal = (u->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(u);
- DrawSprite(u->GetImage(dir, image_type), pal, px + (rtl ? -offset.x : offset.x), ScaleGUITrad(6) + offset.y);
+ VehicleSpriteSeq seq;
+ u->GetImage(dir, image_type, &seq);
+ DrawSprite(seq.sprite, pal, px + (rtl ? -offset.x : offset.x), ScaleGUITrad(6) + offset.y);
}
px += rtl ? -width : width;
diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp
index 4afbe6033..561df3361 100644
--- a/src/saveload/oldloader_sl.cpp
+++ b/src/saveload/oldloader_sl.cpp
@@ -1165,7 +1165,7 @@ static const OldChunks vehicle_chunk[] = {
OCL_SVAR( OC_UINT8, Vehicle, owner ),
OCL_SVAR( OC_TILE, Vehicle, tile ),
- OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, cur_image ),
+ OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_seq.sprite ),
OCL_NULL( 8 ), ///< Vehicle sprite box, calculated automatically
@@ -1258,7 +1258,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
if (v == NULL) continue;
v->refit_cap = v->cargo_cap;
- SpriteID sprite = v->cur_image;
+ SpriteID sprite = v->sprite_seq.sprite;
/* no need to override other sprites */
if (IsInsideMM(sprite, 1460, 1465)) {
sprite += 580; // aircraft smoke puff
@@ -1269,7 +1269,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
} else if (IsInsideMM(sprite, 2516, 2539)) {
sprite += 1385; // rotor or disaster-related vehicles
}
- v->cur_image = sprite;
+ v->sprite_seq.sprite = sprite;
switch (v->type) {
case VEH_TRAIN: {
diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp
index ebc5fc421..4c40f52b2 100644
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -436,21 +436,21 @@ void AfterLoadVehicles(bool part_of_load)
case VEH_TRAIN:
case VEH_SHIP:
- v->cur_image = v->GetImage(v->direction, EIT_ON_MAP);
+ v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
break;
case VEH_AIRCRAFT:
if (Aircraft::From(v)->IsNormalAircraft()) {
- v->cur_image = v->GetImage(v->direction, EIT_ON_MAP);
+ v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
- /* The plane's shadow will have the same image as the plane */
+ /* The plane's shadow will have the same image as the plane, but no colour */
Vehicle *shadow = v->Next();
- shadow->cur_image = v->cur_image;
+ shadow->sprite_seq.sprite = v->sprite_seq.sprite;
/* In the case of a helicopter we will update the rotor sprites */
if (v->subtype == AIR_HELICOPTER) {
Vehicle *rotor = shadow->Next();
- rotor->cur_image = GetRotorImage(Aircraft::From(v), EIT_ON_MAP);
+ GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq);
}
UpdateAircraftCache(Aircraft::From(v), true);
@@ -796,7 +796,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, 0, 163),
SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, 164, SL_MAX_VERSION),
- SLE_VAR(Vehicle, cur_image, SLE_FILE_U16 | SLE_VAR_U32),
+ SLE_VAR(Vehicle, sprite_seq.sprite, SLE_FILE_U16 | SLE_VAR_U32),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
@@ -836,7 +836,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, 5, SL_MAX_VERSION),
- SLE_VAR(Vehicle, cur_image, SLE_FILE_U16 | SLE_VAR_U32),
+ SLE_VAR(Vehicle, sprite_seq.sprite, SLE_FILE_U16 | SLE_VAR_U32),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
diff --git a/src/ship.h b/src/ship.h
index 18f04c8fa..c94cbcddb 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -34,7 +34,7 @@ struct Ship FINAL : public SpecializedVehicle<Ship, VEH_SHIP> {
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_SHIP_INC : EXPENSES_SHIP_RUN; }
void PlayLeaveStationSound() const;
bool IsPrimaryVehicle() const { return true; }
- SpriteID GetImage(Direction direction, EngineImageType image_type) const;
+ void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->cur_speed / 2; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; }
int GetCurrentMaxSpeed() const { return min(this->vcache.cached_max_speed, this->current_order.GetMaxSpeed() * 2); }
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index a24fb3510..a4b84ae87 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -70,30 +70,32 @@ static inline TrackBits GetTileShipTrackStatus(TileIndex tile)
return TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0));
}
-static SpriteID GetShipIcon(EngineID engine, EngineImageType image_type)
+static void GetShipIcon(EngineID engine, EngineImageType image_type, VehicleSpriteSeq *result)
{
const Engine *e = Engine::Get(engine);
uint8 spritenum = e->u.ship.image_index;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleIcon(engine, DIR_W, image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleIcon(engine, DIR_W, image_type, result);
+ if (result->IsValid()) return;
spritenum = e->original_image_index;
}
assert(IsValidImageIndex<VEH_SHIP>(spritenum));
- return DIR_W + _ship_sprites[spritenum];
+ result->Set(DIR_W + _ship_sprites[spritenum]);
}
void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
{
- SpriteID sprite = GetShipIcon(engine, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetShipIcon(engine, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
preferred_x = Clamp(preferred_x,
left - UnScaleGUI(real_sprite->x_offs),
right - UnScaleGUI(real_sprite->width) - UnScaleGUI(real_sprite->x_offs));
- DrawSprite(sprite, pal, preferred_x, y);
+ DrawSprite(seq.sprite, pal, preferred_x, y);
}
/**
@@ -107,7 +109,10 @@ void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine
*/
void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
{
- const Sprite *spr = GetSprite(GetShipIcon(engine, image_type), ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetShipIcon(engine, image_type, &seq);
+
+ const Sprite *spr = GetSprite(seq.sprite, ST_NORMAL);
width = UnScaleGUI(spr->width);
height = UnScaleGUI(spr->height);
@@ -115,19 +120,19 @@ void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, i
yoffs = UnScaleGUI(spr->y_offs);
}
-SpriteID Ship::GetImage(Direction direction, EngineImageType image_type) const
+void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
{
uint8 spritenum = this->spritenum;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleSprite(this, direction, image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleSprite(this, direction, image_type, result);
+ if (result->IsValid()) return;
spritenum = this->GetEngine()->original_image_index;
}
assert(IsValidImageIndex<VEH_SHIP>(spritenum));
- return _ship_sprites[spritenum] + direction;
+ result->Set(_ship_sprites[spritenum] + direction);
}
static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance)
@@ -710,7 +715,7 @@ CommandCost CmdBuildShip(TileIndex tile, DoCommandFlag flags, const Engine *e, u
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_ships);
v->date_of_last_service = _date;
v->build_year = _cur_year;
- v->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
v->UpdateCache();
diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp
index 7ad2e8473..f827b0a31 100644
--- a/src/ship_gui.cpp
+++ b/src/ship_gui.cpp
@@ -35,15 +35,17 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec
{
bool rtl = _current_text_dir == TD_RTL;
- SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
int width = UnScaleGUI(real_sprite->width);
int x_offs = UnScaleGUI(real_sprite->x_offs);
int x = rtl ? right - width - x_offs : left - x_offs;
y += ScaleGUITrad(10);
- DrawSprite(sprite, GetVehiclePalette(v), x, y);
+ DrawSprite(seq.sprite, GetVehiclePalette(v), x, y);
if (v->index == selection) {
x += x_offs;
diff --git a/src/train.h b/src/train.h
index 280d59ebd..82e33b67d 100644
--- a/src/train.h
+++ b/src/train.h
@@ -114,7 +114,7 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
ExpensesType GetExpenseType(bool income) const { return income ? EXPENSES_TRAIN_INC : EXPENSES_TRAIN_RUN; }
void PlayLeaveStationSound() const;
bool IsPrimaryVehicle() const { return this->IsFrontEngine(); }
- SpriteID GetImage(Direction direction, EngineImageType image_type) const;
+ void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const;
int GetDisplaySpeed() const { return this->gcache.last_speed; }
int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; }
Money GetRunningCost() const;
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 699f0c144..34e7ef254 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -482,41 +482,40 @@ static SpriteID GetDefaultTrainSprite(uint8 spritenum, Direction direction)
* @param image_type Visualisation context.
* @return Sprite to display.
*/
-SpriteID Train::GetImage(Direction direction, EngineImageType image_type) const
+void Train::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
{
uint8 spritenum = this->spritenum;
- SpriteID sprite;
if (HasBit(this->flags, VRF_REVERSE_DIRECTION)) direction = ReverseDir(direction);
if (is_custom_sprite(spritenum)) {
- sprite = GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type);
- if (sprite != 0) return sprite;
+ GetCustomVehicleSprite(this, (Direction)(direction + 4 * IS_CUSTOM_SECONDHEAD_SPRITE(spritenum)), image_type, result);
+ if (result->IsValid()) return;
spritenum = this->GetEngine()->original_image_index;
}
assert(IsValidImageIndex<VEH_TRAIN>(spritenum));
- sprite = GetDefaultTrainSprite(spritenum, direction);
+ SpriteID sprite = GetDefaultTrainSprite(spritenum, direction);
if (this->cargo.StoredCount() >= this->cargo_cap / 2U) sprite += _wagon_full_adder[spritenum];
- return sprite;
+ result->Set(sprite);
}
-static SpriteID GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType image_type)
+static void GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType image_type, VehicleSpriteSeq *result)
{
const Engine *e = Engine::Get(engine);
Direction dir = rear_head ? DIR_E : DIR_W;
uint8 spritenum = e->u.rail.image_index;
if (is_custom_sprite(spritenum)) {
- SpriteID sprite = GetCustomVehicleIcon(engine, dir, image_type);
- if (sprite != 0) {
+ GetCustomVehicleIcon(engine, dir, image_type, result);
+ if (result->IsValid()) {
if (e->GetGRF() != NULL) {
y += ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch);
}
- return sprite;
+ return;
}
spritenum = Engine::Get(engine)->original_image_index;
@@ -524,7 +523,7 @@ static SpriteID GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImage
if (rear_head) spritenum++;
- return GetDefaultTrainSprite(spritenum, DIR_W);
+ result->Set(GetDefaultTrainSprite(spritenum, DIR_W));
}
void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engine, PaletteID pal, EngineImageType image_type)
@@ -533,24 +532,28 @@ void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engin
int yf = y;
int yr = y;
- SpriteID spritef = GetRailIcon(engine, false, yf, image_type);
- SpriteID spriter = GetRailIcon(engine, true, yr, image_type);
- const Sprite *real_spritef = GetSprite(spritef, ST_NORMAL);
- const Sprite *real_spriter = GetSprite(spriter, ST_NORMAL);
+ VehicleSpriteSeq seqf, seqr;
+ GetRailIcon(engine, false, yf, image_type, &seqf);
+ GetRailIcon(engine, true, yr, image_type, &seqr);
+
+ const Sprite *real_spritef = GetSprite(seqf.sprite, ST_NORMAL);
+ const Sprite *real_spriter = GetSprite(seqr.sprite, ST_NORMAL);
preferred_x = Clamp(preferred_x,
left - UnScaleGUI(real_spritef->x_offs) + ScaleGUITrad(14),
right - UnScaleGUI(real_spriter->width) - UnScaleGUI(real_spriter->x_offs) - ScaleGUITrad(15));
- DrawSprite(spritef, pal, preferred_x - ScaleGUITrad(14), yf);
- DrawSprite(spriter, pal, preferred_x + ScaleGUITrad(15), yr);
+ DrawSprite(seqf.sprite, pal, preferred_x - ScaleGUITrad(14), yf);
+ DrawSprite(seqr.sprite, pal, preferred_x + ScaleGUITrad(15), yr);
} else {
- SpriteID sprite = GetRailIcon(engine, false, y, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetRailIcon(engine, false, y, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
preferred_x = Clamp(preferred_x,
left - UnScaleGUI(real_sprite->x_offs),
right - UnScaleGUI(real_sprite->width) - UnScaleGUI(real_sprite->x_offs));
- DrawSprite(sprite, pal, preferred_x, y);
+ DrawSprite(seq.sprite, pal, preferred_x, y);
}
}
@@ -567,8 +570,10 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs,
{
int y = 0;
- SpriteID sprite = GetRailIcon(engine, false, y, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ GetRailIcon(engine, false, y, image_type, &seq);
+
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
width = UnScaleGUI(real_sprite->width);
height = UnScaleGUI(real_sprite->height);
@@ -576,8 +581,8 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs,
yoffs = UnScaleGUI(real_sprite->y_offs);
if (RailVehInfo(engine)->railveh_type == RAILVEH_MULTIHEAD) {
- sprite = GetRailIcon(engine, true, y, image_type);
- real_sprite = GetSprite(sprite, ST_NORMAL);
+ GetRailIcon(engine, true, y, image_type, &seq);
+ real_sprite = GetSprite(seq.sprite, ST_NORMAL);
/* Calculate values relative to an imaginary center between the two sprites. */
width = ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) + UnScaleGUI(real_sprite->width) + UnScaleGUI(real_sprite->x_offs) - xoffs;
@@ -638,7 +643,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const
v->date_of_last_service = _date;
v->build_year = _cur_year;
- v->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
v->group_id = DEFAULT_GROUP;
@@ -706,7 +711,7 @@ static void AddRearEngineToMultiheadedTrain(Train *v)
u->engine_type = v->engine_type;
u->date_of_last_service = v->date_of_last_service;
u->build_year = v->build_year;
- u->cur_image = SPR_IMG_QUERY;
+ u->sprite_seq.Set(SPR_IMG_QUERY);
u->random_bits = VehicleRandomBits();
v->SetMultiheaded();
u->SetMultiheaded();
@@ -772,7 +777,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, DoCommandFlag flags, const Engin
v->SetServiceInterval(Company::Get(_current_company)->settings.vehicle.servint_trains);
v->date_of_last_service = _date;
v->build_year = _cur_year;
- v->cur_image = SPR_IMG_QUERY;
+ v->sprite_seq.Set(SPR_IMG_QUERY);
v->random_bits = VehicleRandomBits();
if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
diff --git a/src/train_gui.cpp b/src/train_gui.cpp
index 219d016ec..42ba87c84 100644
--- a/src/train_gui.cpp
+++ b/src/train_gui.cpp
@@ -124,7 +124,9 @@ void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID select
if (rtl ? px + width > 0 : px - width < max_width) {
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
- DrawSprite(v->GetImage(dir, image_type), pal, px + (rtl ? -offset.x : offset.x), height / 2 + offset.y);
+ VehicleSpriteSeq seq;
+ v->GetImage(dir, image_type, &seq);
+ DrawSprite(seq.sprite, pal, px + (rtl ? -offset.x : offset.x), height / 2 + offset.y);
}
if (!v->IsArticulatedPart()) sel_articulated = false;
@@ -383,7 +385,9 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po
pitch = ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch);
}
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
- DrawSprite(u->GetImage(dir, EIT_IN_DETAILS), pal, px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + pitch);
+ VehicleSpriteSeq seq;
+ u->GetImage(dir, EIT_IN_DETAILS, &seq);
+ DrawSprite(seq.sprite, pal, px + (rtl ? -offset.x : offset.x), y - line_height * vscroll_pos + sprite_y_offset + pitch);
}
px += rtl ? -width : width;
dx += width;
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index da2cfeb80..c5261407b 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -1008,7 +1008,6 @@ void CallVehicleTicks()
*/
static void DoDrawVehicle(const Vehicle *v)
{
- SpriteID image = v->cur_image;
PaletteID pal = PAL_NONE;
if (v->vehstatus & VS_DEFPAL) pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
@@ -1023,7 +1022,7 @@ static void DoDrawVehicle(const Vehicle *v)
if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
}
- AddSortableSpriteToDraw(image, pal, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
+ AddSortableSpriteToDraw(v->sprite_seq.sprite, pal, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
v->x_extent, v->y_extent, v->z_extent, v->z_pos, shadowed, v->x_bb_offs, v->y_bb_offs);
}
@@ -1487,10 +1486,9 @@ void Vehicle::UpdatePosition()
*/
void Vehicle::UpdateViewport(bool dirty)
{
- int img = this->cur_image;
- Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
- const Sprite *spr = GetSprite(img, ST_NORMAL);
+ const Sprite *spr = GetSprite(this->sprite_seq.sprite, ST_NORMAL);
+ Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
pt.x += spr->x_offs;
pt.y += spr->y_offs;
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index f923c2d79..30366e5ea 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -126,6 +126,45 @@ struct VehicleCache {
byte cached_vis_effect; ///< Visual effect to show (see #VisualEffect)
};
+/** Sprite sequence for a vehicle part. */
+struct VehicleSpriteSeq {
+ SpriteID sprite;
+
+ bool operator==(const VehicleSpriteSeq &other) const
+ {
+ return this->sprite == other.sprite;
+ }
+
+ bool operator!=(const VehicleSpriteSeq &other) const
+ {
+ return !this->operator==(other);
+ }
+
+ /**
+ * Check whether the sequence contains any sprites.
+ */
+ bool IsValid() const
+ {
+ return this->sprite != 0;
+ }
+
+ /**
+ * Clear all information.
+ */
+ void Clear()
+ {
+ this->sprite = 0;
+ }
+
+ /**
+ * Assign a single sprite to the sequence.
+ */
+ void Set(SpriteID sprite)
+ {
+ this->sprite = sprite;
+ }
+};
+
/** A vehicle pool for a little over 1 million vehicles. */
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
extern VehiclePool _vehicle_pool;
@@ -220,7 +259,7 @@ public:
* 0xff == reserved for another custom sprite
*/
byte spritenum;
- SpriteID cur_image; ///< sprite number for this vehicle
+ VehicleSpriteSeq sprite_seq; ///< Vehicle appearance.
byte x_extent; ///< x-extent of vehicle bounding box
byte y_extent; ///< y-extent of vehicle bounding box
byte z_extent; ///< z-extent of vehicle bounding box
@@ -380,9 +419,9 @@ public:
/**
* Gets the sprite to show for the given direction
* @param direction the direction the vehicle is facing
- * @return the sprite for the given vehicle in the given direction
+ * @param [out] result Vehicle sprite sequence.
*/
- virtual SpriteID GetImage(Direction direction, EngineImageType image_type) const { return 0; }
+ virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const { result->Clear(); }
const GRFFile *GetGRF() const;
uint32 GetGRFID() const;
@@ -1079,9 +1118,12 @@ struct SpecializedVehicle : public Vehicle {
/* Explicitly choose method to call to prevent vtable dereference -
* it gives ~3% runtime improvements in games with many vehicles */
if (update_delta) ((T *)this)->T::UpdateDeltaXY(this->direction);
- SpriteID old_image = this->cur_image;
- this->cur_image = ((T *)this)->T::GetImage(this->direction, EIT_ON_MAP);
- if (force_update || this->cur_image != old_image) this->Vehicle::UpdateViewport(true);
+ VehicleSpriteSeq seq;
+ ((T *)this)->T::GetImage(this->direction, EIT_ON_MAP, &seq);
+ if (force_update || this->sprite_seq != seq) {
+ this->sprite_seq = seq;
+ this->Vehicle::UpdateViewport(true);
+ }
}
};
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index 87c119074..3d93e4d30 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -2842,8 +2842,9 @@ int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type)
default:
bool rtl = _current_text_dir == TD_RTL;
- SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
- const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
+ VehicleSpriteSeq seq;
+ v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
+ const Sprite *real_sprite = GetSprite(seq.sprite, ST_NORMAL);
return UnScaleGUI(real_sprite->width);
}
}
@@ -2882,8 +2883,10 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
if (total_width >= 2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH) break;
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
+ VehicleSpriteSeq seq;
+ v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
- _cursor.sprite_seq[_cursor.sprite_count].sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
+ _cursor.sprite_seq[_cursor.sprite_count].sprite = seq.sprite;
_cursor.sprite_seq[_cursor.sprite_count].pal = pal;
_cursor.sprite_pos[_cursor.sprite_count].x = rtl ? -total_width : total_width;
_cursor.sprite_pos[_cursor.sprite_count].y = 0;