Update vehicle image on demand when image is continuously updated by GRF

This is for trains/RVs only (to avoid issues with variable sprite bounds)

This largely fixes the performance issues of continuously updating
vehicle images
This commit is contained in:
Jonathan G Rennison 2020-11-08 23:09:01 +00:00
parent cde5e8c79d
commit 99b2698658
3 changed files with 30 additions and 4 deletions

View File

@ -5033,7 +5033,7 @@ def = false
str = STR_CONFIG_SETTING_DISABLE_VEHICLE_IMAGE_UPDATE
strhelp = STR_CONFIG_SETTING_DISABLE_VEHICLE_IMAGE_UPDATE_HELPTEXT
proc = InvalidateAllVehicleImageCaches
cat = SC_ADVANCED
cat = SC_EXPERT
; For the dedicated build we'll enable dates in logs by default.
[SDTC_BOOL]

View File

@ -1542,6 +1542,17 @@ static void DoDrawVehicle(const Vehicle *v)
if (to != TO_INVALID && (IsTransparencySet(to) || IsInvisibilitySet(to))) return;
}
{
Vehicle *v_mutable = const_cast<Vehicle *>(v);
if (HasBit(v_mutable->vcache.cached_veh_flags, VCF_IMAGE_REFRESH) && v_mutable->cur_image_valid_dir != INVALID_DIR) {
VehicleSpriteSeq seq;
v_mutable->GetImage(v_mutable->cur_image_valid_dir, EIT_ON_MAP, &seq);
v_mutable->sprite_seq = seq;
v_mutable->UpdateSpriteSeqBound();
ClrBit(v_mutable->vcache.cached_veh_flags, VCF_IMAGE_REFRESH);
}
}
StartSpriteCombine();
for (uint i = 0; i < v->sprite_seq.count; ++i) {
PaletteID pal2 = v->sprite_seq.seq[i].pal;
@ -3787,6 +3798,8 @@ char *Vehicle::DumpVehicleFlags(char *b, const char *last, bool include_tile) co
dump('d', HasBit(this->vcache.cached_veh_flags, VCF_IS_DRAWN));
dump('t', HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER));
dump('s', HasBit(this->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE));
dump('R', HasBit(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH));
dump('N', HasBit(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH_NEXT));
if (this->IsGroundVehicle()) {
uint16 gv_flags = this->GetGroundVehicleFlags();
b += seprintf(b, last, ", gvf:");

View File

@ -140,6 +140,8 @@ enum VehicleCacheFlags {
VCF_IS_DRAWN = 2, ///< Vehicle is currently drawn
VCF_REDRAW_ON_TRIGGER = 3, ///< Clear cur_image_valid_dir on changes to waiting_triggers (valid only for the first engine)
VCF_REDRAW_ON_SPEED_CHANGE = 4, ///< Clear cur_image_valid_dir on changes to cur_speed (ground vehicles) or aircraft movement state (aircraft) (valid only for the first engine)
VCF_IMAGE_REFRESH = 5, ///< Image should be refreshed before drawing
VCF_IMAGE_REFRESH_NEXT = 6, ///< Set VCF_IMAGE_REFRESH in next UpdateViewport call, if the image is not updated there
};
/** Cached often queried values common to all vehicles. */
@ -1280,15 +1282,26 @@ struct SpecializedVehicle : public Vehicle {
_sprite_group_resolve_check_veh_check = true;
VehicleSpriteSeq seq;
((T *)this)->T::GetImage(current_direction, EIT_ON_MAP, &seq);
this->cur_image_valid_dir = (_sprite_group_resolve_check_veh_check || _settings_client.gui.disable_vehicle_image_update) ? current_direction : INVALID_DIR;
if (EXPECTED_TYPE == VEH_TRAIN || EXPECTED_TYPE == VEH_ROAD) {
ClrBit(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH);
SB(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH_NEXT, 1, (_sprite_group_resolve_check_veh_check || _settings_client.gui.disable_vehicle_image_update) ? 0 : 1);
this->cur_image_valid_dir = current_direction;
} else {
this->cur_image_valid_dir = (_sprite_group_resolve_check_veh_check || _settings_client.gui.disable_vehicle_image_update) ? current_direction : INVALID_DIR;
}
_sprite_group_resolve_check_veh_check = false;
if (force_update || this->sprite_seq != seq) {
this->sprite_seq = seq;
this->UpdateSpriteSeqBound();
this->Vehicle::UpdateViewport(true);
}
} else if (force_update) {
this->Vehicle::UpdateViewport(true);
} else {
if ((EXPECTED_TYPE == VEH_TRAIN || EXPECTED_TYPE == VEH_ROAD) && HasBit(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH_NEXT)) {
SetBit(this->vcache.cached_veh_flags, VCF_IMAGE_REFRESH);
}
if (force_update) {
this->Vehicle::UpdateViewport(true);
}
}
}