Cache sprite sequence bounds for vehicles

This commit is contained in:
Jonathan G Rennison
2018-01-19 19:13:01 +00:00
parent 5b226adc75
commit d730cfd51d
12 changed files with 71 additions and 41 deletions

View File

@@ -208,8 +208,7 @@ void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID en
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetAircraftIcon(engine, image_type, &seq); GetAircraftIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
preferred_x = Clamp(preferred_x, preferred_x = Clamp(preferred_x,
left - UnScaleGUI(rect.left), left - UnScaleGUI(rect.left),
right - UnScaleGUI(rect.right)); right - UnScaleGUI(rect.right));
@@ -238,8 +237,7 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetAircraftIcon(engine, image_type, &seq); GetAircraftIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
width = UnScaleGUI(rect.right - rect.left + 1); width = UnScaleGUI(rect.right - rect.left + 1);
height = UnScaleGUI(rect.bottom - rect.top + 1); height = UnScaleGUI(rect.bottom - rect.top + 1);
@@ -371,6 +369,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine *
w->spritenum = 0xFF; w->spritenum = 0xFF;
w->subtype = AIR_ROTOR; w->subtype = AIR_ROTOR;
w->sprite_seq.Set(SPR_ROTOR_STOPPED); w->sprite_seq.Set(SPR_ROTOR_STOPPED);
w->UpdateSpriteSeqBound();
w->random_bits = VehicleRandomBits(); w->random_bits = VehicleRandomBits();
/* Use rotor's air.state to store the rotor animation frame */ /* Use rotor's air.state to store the rotor animation frame */
w->state = HRS_ROTOR_STOPPED; w->state = HRS_ROTOR_STOPPED;
@@ -504,6 +503,7 @@ static void HelicopterTickHandler(Aircraft *v)
} }
u->sprite_seq = seq; u->sprite_seq = seq;
u->UpdateSpriteSeqBound();
u->UpdatePositionAndViewport(); u->UpdatePositionAndViewport();
} }
@@ -524,7 +524,9 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
v->UpdatePosition(); v->UpdatePosition();
v->UpdateViewport(true, false); v->UpdateViewport(true, false);
if (v->subtype == AIR_HELICOPTER) { if (v->subtype == AIR_HELICOPTER) {
GetRotorImage(v, EIT_ON_MAP, &v->Next()->Next()->sprite_seq); Aircraft *rotor = v->Next()->Next();
GetRotorImage(v, EIT_ON_MAP, &rotor->sprite_seq);
rotor->UpdateSpriteSeqBound();
} }
Aircraft *u = v->Next(); Aircraft *u = v->Next();
@@ -537,6 +539,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z)
safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE); safe_y = Clamp(u->y_pos, 0, MapMaxY() * TILE_SIZE);
u->z_pos = GetSlopePixelZ(safe_x, safe_y); u->z_pos = GetSlopePixelZ(safe_x, safe_y);
u->sprite_seq.CopyWithoutPalette(v->sprite_seq); // the shadow is never coloured u->sprite_seq.CopyWithoutPalette(v->sprite_seq); // the shadow is never coloured
u->sprite_seq_bounds = v->sprite_seq_bounds;
u->UpdatePositionAndViewport(); u->UpdatePositionAndViewport();
@@ -1308,7 +1311,9 @@ void Aircraft::MarkDirty()
this->cur_image_valid_dir = INVALID_DIR; this->cur_image_valid_dir = INVALID_DIR;
this->UpdateViewport(true, false); this->UpdateViewport(true, false);
if (this->subtype == AIR_HELICOPTER) { if (this->subtype == AIR_HELICOPTER) {
GetRotorImage(this, EIT_ON_MAP, &this->Next()->Next()->sprite_seq); Aircraft *rotor = this->Next()->Next();
GetRotorImage(this, EIT_ON_MAP, &rotor->sprite_seq);
rotor->UpdateSpriteSeqBound();
} }
} }

View File

@@ -86,8 +86,7 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq); v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
int width = UnScaleGUI(rect.right - rect.left + 1); int width = UnScaleGUI(rect.right - rect.left + 1);
int x_offs = UnScaleGUI(rect.left); int x_offs = UnScaleGUI(rect.left);

View File

@@ -32,6 +32,7 @@ static bool IncrementSprite(EffectVehicle *v, SpriteID last)
{ {
if (v->sprite_seq.seq[0].sprite != last) { if (v->sprite_seq.seq[0].sprite != last) {
v->sprite_seq.seq[0].sprite++; v->sprite_seq.seq[0].sprite++;
v->UpdateSpriteSeqBound();
return true; return true;
} else { } else {
return false; return false;
@@ -42,6 +43,7 @@ static void ChimneySmokeInit(EffectVehicle *v)
{ {
uint32 r = Random(); uint32 r = Random();
v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3)); v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0 + GB(r, 0, 3));
v->UpdateSpriteSeqBound();
v->progress = GB(r, 16, 3); v->progress = GB(r, 16, 3);
} }
@@ -59,6 +61,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) { if (!IncrementSprite(v, SPR_CHIMNEY_SMOKE_7)) {
v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0); v->sprite_seq.Set(SPR_CHIMNEY_SMOKE_0);
} }
v->UpdateSpriteSeqBound();
v->progress = 7; v->progress = 7;
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -69,6 +72,7 @@ static bool ChimneySmokeTick(EffectVehicle *v)
static void SteamSmokeInit(EffectVehicle *v) static void SteamSmokeInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_STEAM_SMOKE_0); v->sprite_seq.Set(SPR_STEAM_SMOKE_0);
v->UpdateSpriteSeqBound();
v->progress = 12; v->progress = 12;
} }
@@ -88,6 +92,7 @@ static bool SteamSmokeTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
moved = true; moved = true;
} }
@@ -99,6 +104,7 @@ static bool SteamSmokeTick(EffectVehicle *v)
static void DieselSmokeInit(EffectVehicle *v) static void DieselSmokeInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_DIESEL_SMOKE_0); v->sprite_seq.Set(SPR_DIESEL_SMOKE_0);
v->UpdateSpriteSeqBound();
v->progress = 0; v->progress = 0;
} }
@@ -114,6 +120,7 @@ static bool DieselSmokeTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -123,6 +130,7 @@ static bool DieselSmokeTick(EffectVehicle *v)
static void ElectricSparkInit(EffectVehicle *v) static void ElectricSparkInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_ELECTRIC_SPARK_0); v->sprite_seq.Set(SPR_ELECTRIC_SPARK_0);
v->UpdateSpriteSeqBound();
v->progress = 1; v->progress = 1;
} }
@@ -137,6 +145,7 @@ static bool ElectricSparkTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -146,6 +155,7 @@ static bool ElectricSparkTick(EffectVehicle *v)
static void SmokeInit(EffectVehicle *v) static void SmokeInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_SMOKE_0); v->sprite_seq.Set(SPR_SMOKE_0);
v->UpdateSpriteSeqBound();
v->progress = 12; v->progress = 12;
} }
@@ -165,6 +175,7 @@ static bool SmokeTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
moved = true; moved = true;
} }
@@ -176,6 +187,7 @@ static bool SmokeTick(EffectVehicle *v)
static void ExplosionLargeInit(EffectVehicle *v) static void ExplosionLargeInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_EXPLOSION_LARGE_0); v->sprite_seq.Set(SPR_EXPLOSION_LARGE_0);
v->UpdateSpriteSeqBound();
v->progress = 0; v->progress = 0;
} }
@@ -187,6 +199,7 @@ static bool ExplosionLargeTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -196,6 +209,7 @@ static bool ExplosionLargeTick(EffectVehicle *v)
static void BreakdownSmokeInit(EffectVehicle *v) static void BreakdownSmokeInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0); v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
v->UpdateSpriteSeqBound();
v->progress = 0; v->progress = 0;
} }
@@ -206,6 +220,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) { if (!IncrementSprite(v, SPR_BREAKDOWN_SMOKE_3)) {
v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0); v->sprite_seq.Set(SPR_BREAKDOWN_SMOKE_0);
} }
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -221,6 +236,7 @@ static bool BreakdownSmokeTick(EffectVehicle *v)
static void ExplosionSmallInit(EffectVehicle *v) static void ExplosionSmallInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_EXPLOSION_SMALL_0); v->sprite_seq.Set(SPR_EXPLOSION_SMALL_0);
v->UpdateSpriteSeqBound();
v->progress = 0; v->progress = 0;
} }
@@ -232,6 +248,7 @@ static bool ExplosionSmallTick(EffectVehicle *v)
delete v; delete v;
return false; return false;
} }
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
} }
@@ -241,6 +258,7 @@ static bool ExplosionSmallTick(EffectVehicle *v)
static void BulldozerInit(EffectVehicle *v) static void BulldozerInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_BULLDOZER_NE); v->sprite_seq.Set(SPR_BULLDOZER_NE);
v->UpdateSpriteSeqBound();
v->progress = 0; v->progress = 0;
v->animation_state = 0; v->animation_state = 0;
v->animation_substate = 0; v->animation_substate = 0;
@@ -292,6 +310,7 @@ static bool BulldozerTick(EffectVehicle *v)
const BulldozerMovement *b = &_bulldozer_movement[v->animation_state]; const BulldozerMovement *b = &_bulldozer_movement[v->animation_state];
v->sprite_seq.Set(SPR_BULLDOZER_NE + b->image); v->sprite_seq.Set(SPR_BULLDOZER_NE + b->image);
v->UpdateSpriteSeqBound();
v->x_pos += _inc_by_dir[b->direction].x; v->x_pos += _inc_by_dir[b->direction].x;
v->y_pos += _inc_by_dir[b->direction].y; v->y_pos += _inc_by_dir[b->direction].y;
@@ -314,6 +333,7 @@ static bool BulldozerTick(EffectVehicle *v)
static void BubbleInit(EffectVehicle *v) static void BubbleInit(EffectVehicle *v)
{ {
v->sprite_seq.Set(SPR_BUBBLE_GENERATE_0); v->sprite_seq.Set(SPR_BUBBLE_GENERATE_0);
v->UpdateSpriteSeqBound();
v->spritenum = 0; v->spritenum = 0;
v->progress = 0; v->progress = 0;
} }
@@ -477,6 +497,7 @@ static bool BubbleTick(EffectVehicle *v)
if (v->spritenum == 0) { if (v->spritenum == 0) {
v->sprite_seq.seq[0].sprite++; v->sprite_seq.seq[0].sprite++;
v->UpdateSpriteSeqBound();
if (v->sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) { if (v->sprite_seq.seq[0].sprite < SPR_BUBBLE_GENERATE_3) {
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();
return true; return true;
@@ -523,6 +544,7 @@ static bool BubbleTick(EffectVehicle *v)
v->y_pos += b->y; v->y_pos += b->y;
v->z_pos += b->z; v->z_pos += b->z;
v->sprite_seq.Set(SPR_BUBBLE_0 + b->image); v->sprite_seq.Set(SPR_BUBBLE_0 + b->image);
v->UpdateSpriteSeqBound();
v->UpdatePositionAndViewport(); v->UpdatePositionAndViewport();

View File

@@ -151,8 +151,7 @@ void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID eng
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetRoadVehIcon(engine, image_type, &seq); GetRoadVehIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
preferred_x = Clamp(preferred_x, preferred_x = Clamp(preferred_x,
left - UnScaleGUI(rect.left), left - UnScaleGUI(rect.left),
right - UnScaleGUI(rect.right)); right - UnScaleGUI(rect.right));
@@ -174,8 +173,7 @@ void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetRoadVehIcon(engine, image_type, &seq); GetRoadVehIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
width = UnScaleGUI(rect.right - rect.left + 1); width = UnScaleGUI(rect.right - rect.left + 1);
height = UnScaleGUI(rect.bottom - rect.top + 1); height = UnScaleGUI(rect.bottom - rect.top + 1);

View File

@@ -1270,6 +1270,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
sprite += 1385; // rotor or disaster-related vehicles sprite += 1385; // rotor or disaster-related vehicles
} }
v->sprite_seq.seq[0].sprite = sprite; v->sprite_seq.seq[0].sprite = sprite;
v->UpdateSpriteSeqBound();
switch (v->type) { switch (v->type) {
case VEH_TRAIN: { case VEH_TRAIN: {

View File

@@ -439,20 +439,24 @@ void AfterLoadVehicles(bool part_of_load)
case VEH_TRAIN: case VEH_TRAIN:
case VEH_SHIP: case VEH_SHIP:
v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq); v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
v->UpdateSpriteSeqBound();
break; break;
case VEH_AIRCRAFT: case VEH_AIRCRAFT:
if (Aircraft::From(v)->IsNormalAircraft()) { if (Aircraft::From(v)->IsNormalAircraft()) {
v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq); v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
v->UpdateSpriteSeqBound();
/* The plane's shadow will have the same image as the plane, but no colour */ /* The plane's shadow will have the same image as the plane, but no colour */
Vehicle *shadow = v->Next(); Vehicle *shadow = v->Next();
shadow->sprite_seq.CopyWithoutPalette(v->sprite_seq); shadow->sprite_seq.CopyWithoutPalette(v->sprite_seq);
shadow->sprite_seq_bounds = v->sprite_seq_bounds;
/* In the case of a helicopter we will update the rotor sprites */ /* In the case of a helicopter we will update the rotor sprites */
if (v->subtype == AIR_HELICOPTER) { if (v->subtype == AIR_HELICOPTER) {
Vehicle *rotor = shadow->Next(); Vehicle *rotor = shadow->Next();
GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq); GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq);
rotor->UpdateSpriteSeqBound();
} }
UpdateAircraftCache(Aircraft::From(v), true); UpdateAircraftCache(Aircraft::From(v), true);

View File

@@ -94,8 +94,7 @@ void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetShipIcon(engine, image_type, &seq); GetShipIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
preferred_x = Clamp(preferred_x, preferred_x = Clamp(preferred_x,
left - UnScaleGUI(rect.left), left - UnScaleGUI(rect.left),
right - UnScaleGUI(rect.right)); right - UnScaleGUI(rect.right));
@@ -117,8 +116,7 @@ void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, i
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetShipIcon(engine, image_type, &seq); GetShipIcon(engine, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
width = UnScaleGUI(rect.right - rect.left + 1); width = UnScaleGUI(rect.right - rect.left + 1);
height = UnScaleGUI(rect.bottom - rect.top + 1); height = UnScaleGUI(rect.bottom - rect.top + 1);

View File

@@ -38,8 +38,7 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq); v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
int width = UnScaleGUI(rect.right - rect.left + 1); int width = UnScaleGUI(rect.right - rect.left + 1);
int x_offs = UnScaleGUI(rect.left); int x_offs = UnScaleGUI(rect.left);

View File

@@ -609,9 +609,8 @@ void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engin
GetRailIcon(engine, false, yf, image_type, &seqf); GetRailIcon(engine, false, yf, image_type, &seqf);
GetRailIcon(engine, true, yr, image_type, &seqr); GetRailIcon(engine, true, yr, image_type, &seqr);
Rect rectf, rectr; Rect16 rectf = seqf.GetBounds();
seqf.GetBounds(&rectf); Rect16 rectr = seqr.GetBounds();
seqr.GetBounds(&rectr);
preferred_x = SoftClamp(preferred_x, preferred_x = SoftClamp(preferred_x,
left - UnScaleGUI(rectf.left) + ScaleGUITrad(14), left - UnScaleGUI(rectf.left) + ScaleGUITrad(14),
@@ -623,8 +622,7 @@ void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engin
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetRailIcon(engine, false, y, image_type, &seq); GetRailIcon(engine, false, y, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
preferred_x = Clamp(preferred_x, preferred_x = Clamp(preferred_x,
left - UnScaleGUI(rect.left), left - UnScaleGUI(rect.left),
right - UnScaleGUI(rect.right)); right - UnScaleGUI(rect.right));
@@ -649,8 +647,7 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs,
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
GetRailIcon(engine, false, y, image_type, &seq); GetRailIcon(engine, false, y, image_type, &seq);
Rect rect; Rect16 rect = seq.GetBounds();
seq.GetBounds(&rect);
width = UnScaleGUI(rect.right - rect.left + 1); width = UnScaleGUI(rect.right - rect.left + 1);
height = UnScaleGUI(rect.bottom - rect.top + 1); height = UnScaleGUI(rect.bottom - rect.top + 1);
@@ -659,7 +656,7 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs,
if (RailVehInfo(engine)->railveh_type == RAILVEH_MULTIHEAD) { if (RailVehInfo(engine)->railveh_type == RAILVEH_MULTIHEAD) {
GetRailIcon(engine, true, y, image_type, &seq); GetRailIcon(engine, true, y, image_type, &seq);
seq.GetBounds(&rect); rect = seq.GetBounds();
/* Calculate values relative to an imaginary center between the two sprites. */ /* Calculate values relative to an imaginary center between the two sprites. */
width = ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) + UnScaleGUI(rect.right) - xoffs; width = ScaleGUITrad(TRAININFO_DEFAULT_VEHICLE_WIDTH) + UnScaleGUI(rect.right) - xoffs;

View File

@@ -83,25 +83,27 @@ static btree::btree_set<Vehicle *> _vehicles_to_pay_repair;
* Determine shared bounds of all sprites. * Determine shared bounds of all sprites.
* @param [out] bounds Shared bounds. * @param [out] bounds Shared bounds.
*/ */
void VehicleSpriteSeq::GetBounds(Rect *bounds) const Rect16 VehicleSpriteSeq::GetBounds() const
{ {
bounds->left = bounds->top = bounds->right = bounds->bottom = 0; Rect16 bounds;
bounds.left = bounds.top = bounds.right = bounds.bottom = 0;
for (uint i = 0; i < this->count; ++i) { for (uint i = 0; i < this->count; ++i) {
const Sprite *spr = GetSprite(this->seq[i].sprite, ST_NORMAL); const Sprite *spr = GetSprite(this->seq[i].sprite, ST_NORMAL);
if (i == 0) { if (i == 0) {
bounds->left = spr->x_offs; bounds.left = spr->x_offs;
bounds->top = spr->y_offs; bounds.top = spr->y_offs;
bounds->right = spr->width + spr->x_offs - 1; bounds.right = spr->width + spr->x_offs - 1;
bounds->bottom = spr->height + spr->y_offs - 1; bounds.bottom = spr->height + spr->y_offs - 1;
} else { } else {
if (spr->x_offs < bounds->left) bounds->left = spr->x_offs; if (spr->x_offs < bounds.left) bounds.left = spr->x_offs;
if (spr->y_offs < bounds->top) bounds->top = spr->y_offs; if (spr->y_offs < bounds.top) bounds.top = spr->y_offs;
int right = spr->width + spr->x_offs - 1; int right = spr->width + spr->x_offs - 1;
int bottom = spr->height + spr->y_offs - 1; int bottom = spr->height + spr->y_offs - 1;
if (right > bounds->right) bounds->right = right; if (right > bounds.right) bounds.right = right;
if (bottom > bounds->bottom) bounds->bottom = bottom; if (bottom > bounds.bottom) bounds.bottom = bottom;
} }
} }
return bounds;
} }
/** /**
@@ -2013,8 +2015,7 @@ void Vehicle::UpdatePosition()
*/ */
void Vehicle::UpdateViewport(bool dirty) void Vehicle::UpdateViewport(bool dirty)
{ {
Rect new_coord; Rect new_coord = ConvertRect<Rect16, Rect>(this->sprite_seq_bounds);
this->sprite_seq.GetBounds(&new_coord);
Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos); Point pt = RemapCoords(this->x_pos + this->x_offs, this->y_pos + this->y_offs, this->z_pos);
new_coord.left += pt.x; new_coord.left += pt.x;

View File

@@ -191,7 +191,7 @@ struct VehicleSpriteSeq {
} }
} }
void GetBounds(Rect *bounds) const; Rect16 GetBounds() const;
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const; void Draw(int x, int y, PaletteID default_pal, bool force_pal) const;
}; };
@@ -288,6 +288,7 @@ public:
*/ */
byte spritenum; byte spritenum;
VehicleSpriteSeq sprite_seq; ///< Vehicle appearance. VehicleSpriteSeq sprite_seq; ///< Vehicle appearance.
Rect16 sprite_seq_bounds;
byte x_extent; ///< x-extent of vehicle bounding box byte x_extent; ///< x-extent of vehicle bounding box
byte y_extent; ///< y-extent of vehicle bounding box byte y_extent; ///< y-extent of vehicle bounding box
byte z_extent; ///< z-extent of vehicle bounding box byte z_extent; ///< z-extent of vehicle bounding box
@@ -1054,6 +1055,11 @@ public:
} }
bool IsDrawn() const; bool IsDrawn() const;
inline void UpdateSpriteSeqBound()
{
this->sprite_seq_bounds = this->sprite_seq.GetBounds();
}
}; };
/** /**
@@ -1236,6 +1242,7 @@ struct SpecializedVehicle : public Vehicle {
_sprite_group_resolve_check_veh_check = false; _sprite_group_resolve_check_veh_check = false;
if (force_update || this->sprite_seq != seq) { if (force_update || this->sprite_seq != seq) {
this->sprite_seq = seq; this->sprite_seq = seq;
this->UpdateSpriteSeqBound();
this->Vehicle::UpdateViewport(true); this->Vehicle::UpdateViewport(true);
} }
} else if (force_update) { } else if (force_update) {

View File

@@ -3487,8 +3487,7 @@ int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type)
bool rtl = _current_text_dir == TD_RTL; bool rtl = _current_text_dir == TD_RTL;
VehicleSpriteSeq seq; VehicleSpriteSeq seq;
v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq); v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
Rect rec; Rect16 rec = seq.GetBounds();
seq.GetBounds(&rec);
return UnScaleGUI(rec.right - rec.left + 1); return UnScaleGUI(rec.right - rec.left + 1);
} }
} }