|
@@ -70,120 +70,131 @@ ScopeResolver::ScopeResolver(ResolverObj
|
|
|
|
|
|
ScopeResolver::~ScopeResolver() {}
|
|
|
|
|
|
/**
|
|
|
* Get a few random bits. Default implementation has no random bits.
|
|
|
* @return Random bits.
|
|
|
*/
|
|
|
/* virtual */ uint32 ScopeResolver::GetRandomBits() const
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the triggers. Base class returns \c 0 to prevent trouble.
|
|
|
* @return The triggers.
|
|
|
*/
|
|
|
/* virtual */ uint32 ScopeResolver::GetTriggers() const
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Set the triggers. Base class implementation does nothing.
|
|
|
* @param triggers Triggers to set.
|
|
|
*/
|
|
|
/* virtual */ void ScopeResolver::SetTriggers(int triggers) const {}
|
|
|
|
|
|
/**
|
|
|
* Get a variable value. Default implementation has no available variables.
|
|
|
* @param variable Variable to read
|
|
|
* @param parameter Parameter for 60+x variables
|
|
|
* @param[out] available Set to false, in case the variable does not exist.
|
|
|
* @return Value
|
|
|
*/
|
|
|
/* virtual */ uint32 ScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
|
|
|
{
|
|
|
DEBUG(grf, 1, "Unhandled scope variable 0x%X", variable);
|
|
|
*available = false;
|
|
|
return UINT_MAX;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Store a value into the persistent storage area (PSA). Default implementation does nothing (for newgrf classes without storage).
|
|
|
* @param pos Position to store into.
|
|
|
* @param value Value to store.
|
|
|
*/
|
|
|
/* virtual */ void ScopeResolver::StorePSA(uint reg, int32 value) {}
|
|
|
|
|
|
|
|
|
/**
|
|
|
* Resolver constructor.
|
|
|
* @param grffile NewGRF file asscoiated with the object (or \c NULL if none).
|
|
|
* @param callback Callback code being resolved (default value is #CBID_NO_CALLBACK).
|
|
|
* @param callback_param1 First parameter (var 10) of the callback (only used when \a callback is also set).
|
|
|
* @param callback_param2 Second parameter (var 18) of the callback (only used when \a callback is also set).
|
|
|
*/
|
|
|
ResolverObject::ResolverObject(const GRFFile *grffile, CallbackID callback, uint32 callback_param1, uint32 callback_param2)
|
|
|
: default_scope(this)
|
|
|
{
|
|
|
this->callback = callback;
|
|
|
this->callback_param1 = callback_param1;
|
|
|
this->callback_param2 = callback_param2;
|
|
|
this->ResetState();
|
|
|
|
|
|
this->grffile = grffile;
|
|
|
}
|
|
|
|
|
|
ResolverObject::~ResolverObject() {}
|
|
|
|
|
|
/**
|
|
|
* Get the real sprites of the grf.
|
|
|
* @param group Group to get.
|
|
|
* @return The available sprite group.
|
|
|
*/
|
|
|
/* virtual */ const SpriteGroup *ResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
|
|
{
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get a specific ScopeResolver.
|
|
|
* Get a resolver for the \a scope.
|
|
|
* @param scope Scope to return.
|
|
|
* @param relative Additional parameter for #VSG_SCOPE_RELATIVE.
|
|
|
* @return ScopeResolver.
|
|
|
* @return The resolver for the requested scope.
|
|
|
*/
|
|
|
/* virtual */ ScopeResolver *ResolverObject::GetScope(VarSpriteGroupScope scope, byte relative)
|
|
|
{
|
|
|
return &this->default_scope;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Rotate val rot times to the right
|
|
|
* @param val the value to rotate
|
|
|
* @param rot the amount of times to rotate
|
|
|
* @return the rotated value
|
|
|
*/
|
|
|
static uint32 RotateRight(uint32 val, uint32 rot)
|
|
|
{
|
|
|
/* Do not rotate more than necessary */
|
|
|
rot %= 32;
|
|
|
|
|
|
return (val >> rot) | (val << (32 - rot));
|
|
|
}
|
|
|
|
|
|
|
|
|
/* Evaluate an adjustment for a variable of the given size.
|
|
|
* U is the unsigned type and S is the signed type to use. */
|
|
|
template <typename U, typename S>
|
|
|
static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ResolverObject *object, U last_value, uint32 value)
|
|
|
{
|
|
|
value >>= adjust->shift_num;
|
|
|
value &= adjust->and_mask;
|
|
|
|
|
|
if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val;
|
|
|
|
|
|
switch (adjust->type) {
|
|
|
case DSGA_TYPE_DIV: value /= (S)adjust->divmod_val; break;
|
|
|
case DSGA_TYPE_MOD: value %= (U)adjust->divmod_val; break;
|
|
|
case DSGA_TYPE_NONE: break;
|
|
|
}
|
|
|
|
|
|
switch (adjust->operation) {
|
|
|
case DSGA_OP_ADD: return last_value + value;
|
|
|
case DSGA_OP_SUB: return last_value - value;
|
|
|
case DSGA_OP_SMIN: return min((S)last_value, (S)value);
|
|
|
case DSGA_OP_SMAX: return max((S)last_value, (S)value);
|
|
|
case DSGA_OP_UMIN: return min((U)last_value, (U)value);
|
|
|
case DSGA_OP_UMAX: return max((U)last_value, (U)value);
|
|
|
case DSGA_OP_SDIV: return value == 0 ? (S)last_value : (S)last_value / (S)value;
|
|
|
case DSGA_OP_SMOD: return value == 0 ? (S)last_value : (S)last_value % (S)value;
|
|
|
case DSGA_OP_UDIV: return value == 0 ? (U)last_value : (U)last_value / (U)value;
|
|
|
case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value;
|