File diff r19737:d7c69e3b4bd4 → r19738:837a139219f0
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -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;