Add several NewGRF variables to vehicle image callback whitelist

Add vehicle flags to control cached image invalidation

Various refactorings
This commit is contained in:
Jonathan G Rennison
2020-08-25 01:26:44 +01:00
parent c82d372d54
commit 810bfd276e
45 changed files with 325 additions and 161 deletions

View File

@@ -22,10 +22,13 @@
#include "company_base.h"
#include "newgrf_railtype.h"
#include "newgrf_roadtype.h"
#include "newgrf_cache_check.h"
#include "ship.h"
#include "safeguards.h"
bool _sprite_group_resolve_check_veh_check = false;
struct WagonOverride {
EngineID *train_id;
uint trains;
@@ -162,7 +165,7 @@ enum TTDPAircraftMovementStates {
* Map OTTD aircraft movement states to TTDPatch style movement states
* (VarAction 2 Variable 0xE2)
*/
static byte MapAircraftMovementState(const Aircraft *v)
byte MapAircraftMovementState(const Aircraft *v)
{
const Station *st = GetTargetAirportIfValid(v);
if (st == nullptr) return AMS_TTDP_FLIGHT_TO_TOWER;
@@ -343,6 +346,14 @@ static byte MapAircraftMovementAction(const Aircraft *v)
/* virtual */ uint32 VehicleScopeResolver::GetTriggers() const
{
if (this->v == nullptr) {
return 0;
} else {
if (_sprite_group_resolve_check_veh_check) {
SetBit(const_cast<Vehicle*>(this->v->First())->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
}
return this->v->waiting_triggers;
}
return this->v == nullptr ? 0 : this->v->waiting_triggers;
}
@@ -444,8 +455,118 @@ static uint32 PositionHelper(const Vehicle *v, bool consecutive)
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
}
static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, byte variable, uint32 parameter, bool *available)
static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, byte variable, uint32 parameter, GetVariableExtra *extra)
{
if (_sprite_group_resolve_check_veh_check) {
switch (variable) {
case 0xC:
case 0x10:
case 0x18:
case 0x1A:
case 0x1C:
case 0x25:
case 0x40:
case 0x41:
case 0x42:
case 0x43:
case 0x47:
case 0x48:
case 0x49:
case 0x4A:
case 0x4B:
case 0x4D:
case 0x60:
case 0x61:
case 0x7D:
case 0x7F:
case 0x80 + 0x0:
case 0x80 + 0x1:
case 0x80 + 0x4:
case 0x80 + 0x5:
case 0x80 + 0xA: // dubious
case 0x80 + 0xB: // dubious
case 0x80 + 0x39:
case 0x80 + 0x3A:
case 0x80 + 0x3B:
case 0x80 + 0x3C:
case 0x80 + 0x3D:
case 0x80 + 0x44:
case 0x80 + 0x45:
case 0x80 + 0x46:
case 0x80 + 0x47:
case 0x80 + 0x5A:
case 0x80 + 0x72:
case 0x80 + 0x7A:
case 0xFF:
break;
case 0x80 + 0x32:
if (extra->mask & (VS_HIDDEN | VS_TRAIN_SLOWING)) {
_sprite_group_resolve_check_veh_check = false;
}
break;
case 0x80 + 0x34:
case 0x80 + 0x35:
if (v->type == VEH_AIRCRAFT) {
_sprite_group_resolve_check_veh_check = false;
} else {
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE);
}
break;
case 0x5F:
case 0x80 + 0x7B:
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
break;
case 0x80 + 0x48:
// VRF_REVERSE_DIRECTION
if (v->type != VEH_TRAIN) {
_sprite_group_resolve_check_veh_check = false;
}
break;
case 0x80 + 0x62:
switch (v->type) {
case VEH_TRAIN:
case VEH_SHIP:
if (extra->mask & 0x7F) {
_sprite_group_resolve_check_veh_check = false;
}
break;
case VEH_ROAD:
break;
case VEH_AIRCRAFT:
if (v == v->First()) {
SetBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_SPEED_CHANGE);
} else {
_sprite_group_resolve_check_veh_check = false;
}
break;
default:
_sprite_group_resolve_check_veh_check = false;
break;
}
break;
case 0xFE:
// vehicle is unloading, VF_CARGO_UNLOADING may disappear without the vehicle being marked dirty
// the vehicle is always marked dirty when VF_CARGO_UNLOADING is set
if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING)) {
_sprite_group_resolve_check_veh_check = false;
}
break;
default:
_sprite_group_resolve_check_veh_check = false;
break;
}
}
/* Calculated vehicle parameters */
switch (variable) {
case 0x25: // Get engine GRF ID
@@ -667,9 +788,12 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
if (parameter == 0x5F) {
/* This seems to be the only variable that makes sense to access via var 61, but is not handled by VehicleGetVariable */
if (_sprite_group_resolve_check_veh_check) {
SetBit(u->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER);
}
return (u->random_bits << 8) | u->waiting_triggers;
} else {
return VehicleGetVariable(u, object, parameter, GetRegister(0x10E), available);
return VehicleGetVariable(u, object, parameter, GetRegister(0x10E), extra);
}
}
/* Not available */
@@ -891,11 +1015,11 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
DEBUG(grf, 1, "Unhandled vehicle variable 0x%X, type 0x%X", variable, (uint)v->type);
*available = false;
extra->available = false;
return UINT_MAX;
}
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
/* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
{
if (this->v == nullptr) {
/* Vehicle does not exist, so we're in a purchase list */
@@ -922,11 +1046,11 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
case 0xF2: return 0; // Cargo subtype
}
*available = false;
extra->available = false;
return UINT_MAX;
}
return VehicleGetVariable(const_cast<Vehicle*>(this->v), this, variable, parameter, available);
return VehicleGetVariable(const_cast<Vehicle*>(this->v), this, variable, parameter, extra);
}
@@ -1206,6 +1330,9 @@ void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
v->InvalidateNewGRFCacheOfChain();
DoTriggerVehicle(v, trigger, 0, true);
if (HasBit(v->First()->vcache.cached_veh_flags, VCF_REDRAW_ON_TRIGGER)) {
v->First()->InvalidateImageCacheOfChain();
}
v->InvalidateNewGRFCacheOfChain();
}
@@ -1325,8 +1452,8 @@ void FillNewGRFVehicleCache(const Vehicle *v)
for (size_t i = 0; i < lengthof(cache_entries); i++) {
/* Only resolve when the cache isn't valid. */
if (HasBit(v->grf_cache.cache_valid, cache_entries[i][1])) continue;
bool stub;
ro.GetScope(VSG_SCOPE_SELF)->GetVariable(cache_entries[i][0], 0, &stub);
GetVariableExtra extra;
ro.GetScope(VSG_SCOPE_SELF)->GetVariable(cache_entries[i][0], 0, &extra);
}
/* Make sure really all bits are set. */