Changeset - r17768:a8b4e13e2113
[Not reviewed]
master
0 6 0
terkhen - 13 years ago 2011-06-12 20:38:46
terkhen@openttd.org
(svn r22563) -Codechange: Use a function for storing values inside the persistent storage.
6 files changed with 45 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/newgrf_airport.cpp
Show inline comments
 
@@ -163,57 +163,70 @@ static const SpriteGroup *AirportResolve
 
	/* Airport action 2s should always have only 1 "loaded" state, but some
 
	 * times things don't follow the spec... */
 
	if (group->num_loaded > 0) return group->loaded[0];
 
	if (group->num_loading > 0) return group->loading[0];
 

	
 
	return NULL;
 
}
 

	
 
static uint32 AirportGetRandomBits(const ResolverObject *object)
 
{
 
	const Station *st = object->u.airport.st;
 
	const TileIndex tile = object->u.airport.tile;
 
	return (st == NULL ? 0 : st->random_bits) | (tile == INVALID_TILE ? 0 : GetStationTileRandomBits(tile) << 16);
 
}
 

	
 
static uint32 AirportGetTriggers(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 
static void AirportSetTriggers(const ResolverObject *object, int triggers)
 
{
 
}
 

	
 
/**
 
 * Store a value into the object's persistent storage.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void AirportStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Station *st = object->u.airport.st;
 
	if (object->scope != VSG_SCOPE_SELF || st == NULL) return;
 
	st->airport.psa.Store(pos, value);
 
}
 

	
 
static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, byte airport_id, byte layout)
 
{
 
	res->GetRandomBits = AirportGetRandomBits;
 
	res->GetTriggers   = AirportGetTriggers;
 
	res->SetTriggers   = AirportSetTriggers;
 
	res->GetVariable   = AirportGetVariable;
 
	res->ResolveReal   = AirportResolveReal;
 
	res->StorePSA      = AirportStorePSA;
 

	
 
	res->psa                  = st != NULL ? &st->airport.psa : NULL;
 
	res->u.airport.st         = st;
 
	res->u.airport.airport_id = airport_id;
 
	res->u.airport.layout     = layout;
 
	res->u.airport.tile       = tile;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
 
	const AirportSpec *as = AirportSpec::Get(airport_id);
 
	res->grffile         = as->grf_prop.grffile;
 
}
 

	
 
SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout)
 
{
 
	const SpriteGroup *group;
 
	ResolverObject object;
 

	
 
	NewAirportResolver(&object, INVALID_TILE, NULL, as->GetIndex(), layout);
 

	
src/newgrf_airporttiles.cpp
Show inline comments
 
@@ -207,51 +207,51 @@ static uint32 AirportTileGetVariable(con
 
		/* Get airport tile ID at offset */
 
		case 0x62: return GetAirportTileIDAtOffset(GetNearbyTile(parameter, tile), st, object->grffile->grfid);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled airport tile variable 0x%X", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
static uint32 AirportTileGetRandomBits(const ResolverObject *object)
 
{
 
	const Station *st = object->u.airport.st;
 
	const TileIndex tile = object->u.airport.tile;
 
	return (st == NULL ? 0 : st->random_bits) | (tile == INVALID_TILE ? 0 : GetStationTileRandomBits(tile) << 16);
 
}
 

	
 
static void AirportTileResolver(ResolverObject *res, const AirportTileSpec *ats, TileIndex tile, Station *st)
 
{
 
	res->GetRandomBits = AirportTileGetRandomBits;
 
	res->GetTriggers   = NULL;
 
	res->SetTriggers   = NULL;
 
	res->GetVariable   = AirportTileGetVariable;
 
	res->ResolveReal   = AirportTileResolveReal;
 
	res->StorePSA      = NULL;
 

	
 
	assert(st != NULL);
 
	res->psa                  = NULL;
 
	res->u.airport.airport_id = st->airport.type;
 
	res->u.airport.st         = st;
 
	res->u.airport.tile       = tile;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
 
	res->grffile         = ats->grf_prop.grffile;
 
}
 

	
 
uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, const AirportTileSpec *ats, Station *st, TileIndex tile)
 
{
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	AirportTileResolver(&object, ats, tile, st);
 
	object.callback = callback;
 
	object.callback_param1 = param1;
 
	object.callback_param2 = param2;
src/newgrf_industries.cpp
Show inline comments
 
@@ -355,57 +355,70 @@ static const SpriteGroup *IndustryResolv
 
{
 
	/* IndustryTile do not have 'real' groups */
 
	return NULL;
 
}
 

	
 
static uint32 IndustryGetRandomBits(const ResolverObject *object)
 
{
 
	const Industry *ind = object->u.industry.ind;
 
	return ind != NULL ? ind->random: 0;
 
}
 

	
 
static uint32 IndustryGetTriggers(const ResolverObject *object)
 
{
 
	const Industry *ind = object->u.industry.ind;
 
	return ind != NULL ? ind->random_triggers : 0;
 
}
 

	
 
static void IndustrySetTriggers(const ResolverObject *object, int triggers)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY);
 
	ind->random_triggers = triggers;
 
}
 

	
 
/**
 
 * Store a value into the object's persistent storage.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void IndustryStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	if (object->scope != VSG_SCOPE_SELF || ind->index == INVALID_INDUSTRY) return;
 
	ind->psa.Store(pos, value);
 
}
 

	
 
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
 
{
 
	res->GetRandomBits = IndustryGetRandomBits;
 
	res->GetTriggers   = IndustryGetTriggers;
 
	res->SetTriggers   = IndustrySetTriggers;
 
	res->GetVariable   = IndustryGetVariable;
 
	res->ResolveReal   = IndustryResolveReal;
 
	res->StorePSA      = IndustryStorePSA;
 

	
 
	res->psa             = &indus->psa;
 
	res->u.industry.tile = tile;
 
	res->u.industry.ind  = indus;
 
	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
 
	res->u.industry.type = type;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
 
	const IndustrySpec *indspec = GetIndustrySpec(type);
 
	res->grffile         = (indspec != NULL ? indspec->grf_prop.grffile : NULL);
 
}
 

	
 
/**
 
 * Perform an industry callback.
 
 * @param callback The callback to perform.
 
 * @param param1 The first parameter.
 
 * @param param2 The second parameter.
 
 * @param industry The industry to do the callback for.
 
 * @param type The type of industry to do the callback for.
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -127,57 +127,70 @@ static uint32 IndustryTileGetRandomBits(
 

	
 
static uint32 IndustryTileGetTriggers(const ResolverObject *object)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	const Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && IsValidTile(tile));
 
	assert(ind->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
 
	if (ind->index == INVALID_INDUSTRY) return 0;
 
	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : ind->random_triggers;
 
}
 

	
 
static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY && IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
 

	
 
	if (object->scope == VSG_SCOPE_SELF) {
 
		SetIndustryTriggers(tile, triggers);
 
	} else {
 
		ind->random_triggers = triggers;
 
	}
 
}
 

	
 
/**
 
 * Store a value into the persistent storage of the object's parent.
 
 * @param object Object that we want to query.
 
 * @param pos Position in the persistent storage to use.
 
 * @param value Value to store.
 
 */
 
void IndustryTileStorePSA(ResolverObject *object, uint pos, int32 value)
 
{
 
	Industry *ind = object->u.industry.ind;
 
	if (object->scope != VSG_SCOPE_PARENT || ind->index == INVALID_INDUSTRY) return;
 
	ind->psa.Store(pos, value);
 
}
 

	
 
static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus)
 
{
 
	res->GetRandomBits = IndustryTileGetRandomBits;
 
	res->GetTriggers   = IndustryTileGetTriggers;
 
	res->SetTriggers   = IndustryTileSetTriggers;
 
	res->GetVariable   = IndustryTileGetVariable;
 
	res->ResolveReal   = IndustryTileResolveReal;
 
	res->StorePSA      = IndustryTileStorePSA;
 

	
 
	res->psa             = &indus->psa;
 
	res->u.industry.tile = tile;
 
	res->u.industry.ind  = indus;
 
	res->u.industry.gfx  = gfx;
 
	res->u.industry.type = indus->type;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 

	
 
	const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
 
	res->grffile         = (its != NULL ? its->grf_prop.grffile : NULL);
 
}
 

	
 
static void IndustryDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte rnd_colour, byte stage, IndustryGfx gfx)
 
{
 
	const DrawTileSprites *dts = group->ProcessRegisters(&stage);
 

	
 
	SpriteID image = dts->ground.sprite;
 
	PaletteID pal  = dts->ground.pal;
 

	
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -92,49 +92,49 @@ static U EvalAdjustT(const Deterministic
 

	
 
	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;
 
		case DSGA_OP_MUL:  return last_value * value;
 
		case DSGA_OP_AND:  return last_value & value;
 
		case DSGA_OP_OR:   return last_value | value;
 
		case DSGA_OP_XOR:  return last_value ^ value;
 
		case DSGA_OP_STO:  _temp_store.Store((U)value, (S)last_value); return last_value;
 
		case DSGA_OP_RST:  return value;
 
		case DSGA_OP_STOP: if (object->psa != NULL) object->psa->Store((U)value, (S)last_value); return last_value;
 
		case DSGA_OP_STOP: if (object->StorePSA != NULL) object->StorePSA(object, (U)value, (S)last_value); return last_value;
 
		case DSGA_OP_ROR:  return RotateRight(last_value, value);
 
		case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2);
 
		case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2);
 
		case DSGA_OP_SHL:  return (U)last_value << ((U)value & 0x1F); // mask 'value' to 5 bits, which should behave the same on all architectures.
 
		case DSGA_OP_SHR:  return (U)last_value >> ((U)value & 0x1F);
 
		case DSGA_OP_SAR:  return (S)last_value >> ((U)value & 0x1F);
 
		default:           return value;
 
	}
 
}
 

	
 

	
 
const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject *object) const
 
{
 
	uint32 last_value = 0;
 
	uint32 value = 0;
 
	uint i;
 

	
 
	object->scope = this->var_scope;
 

	
 
	for (i = 0; i < this->num_adjusts; i++) {
 
		DeterministicSpriteGroupAdjust *adjust = &this->adjusts[i];
 

	
 
		/* Try to get the variable. We shall assume it is available, unless told otherwise. */
 
		bool available = true;
src/newgrf_spritegroup.h
Show inline comments
 
@@ -293,50 +293,48 @@ struct TileLayoutSpriteGroup : SpriteGro
 

	
 
struct IndustryProductionSpriteGroup : SpriteGroup {
 
	IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
 

	
 
	uint8 version;
 
	int16 subtract_input[3];  // signed
 
	uint16 add_output[2];     // unsigned
 
	uint8 again;
 
};
 

	
 

	
 
struct ResolverObject {
 
	CallbackID callback;
 
	uint32 callback_param1;
 
	uint32 callback_param2;
 

	
 
	byte trigger;
 

	
 
	uint32 last_value;          ///< Result of most recent DeterministicSpriteGroup (including procedure calls)
 
	uint32 reseed;              ///< Collects bits to rerandomise while triggering triggers.
 

	
 
	VarSpriteGroupScope scope;  ///< Scope of currently resolved DeterministicSpriteGroup resp. RandomizedSpriteGroup
 
	byte count;                 ///< Additional scope for RandomizedSpriteGroup
 

	
 
	BaseStorageArray *psa;      ///< The persistent storage array of this resolved object.
 

	
 
	const GRFFile *grffile;     ///< GRFFile the resolved SpriteGroup belongs to
 

	
 
	union {
 
		struct {
 
			const struct Vehicle *self;
 
			const struct Vehicle *parent;
 
			EngineID self_type;
 
			bool info_view;                ///< Indicates if the item is being drawn in an info window
 
		} vehicle;
 
		struct {
 
			TileIndex tile;
 
		} canal;
 
		struct {
 
			TileIndex tile;
 
			struct BaseStation *st;
 
			const struct StationSpec *statspec;
 
			CargoID cargo_type;
 
		} station;
 
		struct {
 
			TileIndex tile;
 
			Town *town;                    ///< Town of this house
 
			HouseID house_id;
 
			uint16 initial_random_bits;    ///< Random bits during construction checks
 
			bool not_yet_constructed;      ///< True for construction check
 
@@ -361,27 +359,28 @@ struct ResolverObject {
 
			uint8 station_size;
 
		} generic;
 
		struct {
 
			TileIndex tile;                ///< Tracktile. For track on a bridge this is the southern bridgehead.
 
			TileContext context;           ///< Are we resolving sprites for the upper halftile, or on a bridge?
 
		} routes;
 
		struct {
 
			struct Station *st;            ///< Station of the airport for which the callback is run, or NULL for build gui.
 
			byte airport_id;               ///< Type of airport for which the callback is run
 
			byte layout;                   ///< Layout of the airport to build.
 
			TileIndex tile;                ///< Tile for the callback, only valid for airporttile callbacks.
 
		} airport;
 
		struct {
 
			struct Object *o;              ///< The object the callback is ran for.
 
			TileIndex tile;                ///< The tile related to the object.
 
			uint8 view;                    ///< The view of the object.
 
		} object;
 
	} u;
 

	
 
	uint32 (*GetRandomBits)(const struct ResolverObject*);
 
	uint32 (*GetTriggers)(const struct ResolverObject*);
 
	void (*SetTriggers)(const struct ResolverObject*, int);
 
	uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
 
	const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const RealSpriteGroup*);
 
	void (*StorePSA)(struct ResolverObject*, uint, int32);
 
};
 

	
 
#endif /* NEWGRF_SPRITEGROUP_H */
0 comments (0 inline, 0 general)