changeset 11996:b43cf6c7ea61 draft

(svn r16402) -Codechange: make Resolve a function of SpriteGroup
author rubidium <rubidium@openttd.org>
date Sat, 23 May 2009 15:25:52 +0000
parents fb8b74f42d88
children e2187548a5e4
files src/newgrf_canal.cpp src/newgrf_cargo.cpp src/newgrf_engine.cpp src/newgrf_generic.cpp src/newgrf_house.cpp src/newgrf_industries.cpp src/newgrf_industrytiles.cpp src/newgrf_spritegroup.cpp src/newgrf_spritegroup.h src/newgrf_station.cpp
diffstat 10 files changed, 67 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf_canal.cpp
+++ b/src/newgrf_canal.cpp
@@ -96,7 +96,7 @@
 
 	NewCanalResolver(&object, tile, _water_feature[feature].grffile);
 
-	group = Resolve(_water_feature[feature].group, &object);
+	group = SpriteGroup::Resolve(_water_feature[feature].group, &object);
 	if (group == NULL) return 0;
 
 	return group->GetResult();
--- a/src/newgrf_cargo.cpp
+++ b/src/newgrf_cargo.cpp
@@ -74,7 +74,7 @@
 
 	NewCargoResolver(&object, cs);
 
-	group = Resolve(cs->group, &object);
+	group = SpriteGroup::Resolve(cs->group, &object);
 	if (group == NULL) return 0;
 
 	return group->GetResult();
@@ -91,7 +91,7 @@
 	object.callback_param1 = param1;
 	object.callback_param2 = param2;
 
-	group = Resolve(cs->group, &object);
+	group = SpriteGroup::Resolve(cs->group, &object);
 	if (group == NULL) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -912,7 +912,7 @@
 
 	NewVehicleResolver(&object, engine, v);
 
-	group = Resolve(GetVehicleSpriteGroup(engine, v), &object);
+	group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v), &object);
 	if (group == NULL || group->GetNumResults() == 0) return 0;
 
 	return group->GetResult() + (direction % group->GetNumResults());
@@ -934,7 +934,7 @@
 	object.info_view = info_view;
 
 	const SpriteGroup *group = GetWagonOverrideSpriteSet(engine, CT_DEFAULT, engine);
-	group = Resolve(group, &object);
+	group = SpriteGroup::Resolve(group, &object);
 
 	if (group == NULL || group->GetNumResults() == 0) return 0;
 
@@ -975,7 +975,7 @@
 	object.callback_param1 = param1;
 	object.callback_param2 = param2;
 
-	group = Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
+	group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
 	if (group == NULL) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
@@ -1004,7 +1004,7 @@
 
 	object.u.vehicle.parent = parent;
 
-	group = Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
+	group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), &object);
 	if (group == NULL) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
@@ -1043,7 +1043,7 @@
 	object.callback = CBID_RANDOM_TRIGGER;
 	object.trigger = trigger;
 
-	group = Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
+	group = SpriteGroup::Resolve(GetVehicleSpriteGroup(v->engine_type, v), &object);
 	if (group == NULL) return;
 
 	new_random_bits = Random();
--- a/src/newgrf_generic.cpp
+++ b/src/newgrf_generic.cpp
@@ -139,7 +139,7 @@
 	/* Test each feature callback sprite group. */
 	for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
 		const SpriteGroup *group = it->group;
-		group = Resolve(group, object);
+		group = SpriteGroup::Resolve(group, object);
 		if (group == NULL) continue;
 
 		/* Return NewGRF file if necessary */
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -354,7 +354,7 @@
 	object.callback_param1 = param1;
 	object.callback_param2 = param2;
 
-	group = Resolve(GetHouseSpecs(house_id)->spritegroup, &object);
+	group = SpriteGroup::Resolve(GetHouseSpecs(house_id)->spritegroup, &object);
 	if (group == NULL) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
@@ -422,7 +422,7 @@
 
 	NewHouseResolver(&object, house_id, ti->tile, GetTownByTile(ti->tile));
 
-	group = Resolve(hs->spritegroup, &object);
+	group = SpriteGroup::Resolve(hs->spritegroup, &object);
 	if (group == NULL || group->type != SGT_TILELAYOUT) {
 		/* XXX: This is for debugging purposes really, and shouldn't stay. */
 		DrawGroundSprite(SPR_SHADOW_CELL, PAL_NONE);
@@ -601,7 +601,7 @@
 	object.callback = CBID_RANDOM_TRIGGER;
 	object.trigger = trigger;
 
-	const SpriteGroup *group = Resolve(hs->spritegroup, &object);
+	const SpriteGroup *group = SpriteGroup::Resolve(hs->spritegroup, &object);
 	if (group == NULL) return;
 
 	byte new_random_bits = Random();
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -387,7 +387,7 @@
 	object.callback_param1 = param1;
 	object.callback_param2 = param2;
 
-	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
+	group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
 	if (group == NULL) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
@@ -461,7 +461,7 @@
 	object.callback = CBID_INDUSTRY_LOCATION;
 	_industry_creation_random_bits = seed;
 
-	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
+	group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
 
 	/* Unlike the "normal" cases, not having a valid result means we allow
 	 * the building of the industry, as that's how it's done in TTDP. */
@@ -531,7 +531,7 @@
 		}
 
 		SB(object.callback_param2, 8, 16, loop);
-		const SpriteGroup *tgroup = Resolve(spec->grf_prop.spritegroup, &object);
+		const SpriteGroup *tgroup = SpriteGroup::Resolve(spec->grf_prop.spritegroup, &object);
 		if (tgroup == NULL || tgroup->type != SGT_INDUSTRY_PRODUCTION) break;
 		const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup;
 
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -221,7 +221,7 @@
 	object.callback_param1 = param1;
 	object.callback_param2 = param2;
 
-	group = Resolve(GetIndustryTileSpec(gfx_id)->grf_prop.spritegroup, &object);
+	group = SpriteGroup::Resolve(GetIndustryTileSpec(gfx_id)->grf_prop.spritegroup, &object);
 	if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
 
 	return group->GetCallbackResult();
@@ -245,7 +245,7 @@
 
 	NewIndustryTileResolver(&object, gfx, ti->tile, i);
 
-	group = Resolve(inds->grf_prop.spritegroup, &object);
+	group = SpriteGroup::Resolve(inds->grf_prop.spritegroup, &object);
 	if (group == NULL || group->type != SGT_TILELAYOUT) {
 		return false;
 	} else {
@@ -416,7 +416,7 @@
 	object.callback = CBID_RANDOM_TRIGGER;
 	object.trigger = trigger;
 
-	const SpriteGroup *group = Resolve(itspec->grf_prop.spritegroup, &object);
+	const SpriteGroup *group = SpriteGroup::Resolve(itspec->grf_prop.spritegroup, &object);
 	if (group == NULL) return;
 
 	byte new_random_bits = Random();
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -121,23 +121,23 @@
 }
 
 
-static inline const SpriteGroup *ResolveVariable(const DeterministicSpriteGroup *group, ResolverObject *object)
+const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject *object) const
 {
 	uint32 last_value = 0;
 	uint32 value = 0;
 	uint i;
 
-	object->scope = group->var_scope;
+	object->scope = this->var_scope;
 
-	for (i = 0; i < group->num_adjusts; i++) {
-		DeterministicSpriteGroupAdjust *adjust = &group->adjusts[i];
+	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;
 		if (adjust->variable == 0x7E) {
 			ResolverObject subobject = *object;
 			subobject.procedure_call = true;
-			const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject);
+			const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust->subroutine, &subobject);
 			if (subgroup == NULL) {
 				value = CALLBACK_FAILED;
 			} else {
@@ -150,10 +150,10 @@
 		if (!available) {
 			/* Unsupported property: skip further processing and return either
 			 * the group from the first range or the default group. */
-			return Resolve(group->num_ranges > 0 ? group->ranges[0].group : group->default_group, object);
+			return SpriteGroup::Resolve(this->num_ranges > 0 ? this->ranges[0].group : this->default_group, object);
 		}
 
-		switch (group->size) {
+		switch (this->size) {
 			case DSG_SIZE_BYTE:  value = EvalAdjustT<uint8,  int8> (adjust, object, last_value, value); break;
 			case DSG_SIZE_WORD:  value = EvalAdjustT<uint16, int16>(adjust, object, last_value, value); break;
 			case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, object, last_value, value); break;
@@ -164,7 +164,7 @@
 
 	object->last_value = last_value;
 
-	if (group->num_ranges == 0) {
+	if (this->num_ranges == 0) {
 		/* nvar == 0 is a special case -- we turn our value into a callback result */
 		if (value != CALLBACK_FAILED) value = GB(value, 0, 15);
 		static CallbackResultSpriteGroup nvarzero(0);
@@ -172,34 +172,34 @@
 		return &nvarzero;
 	}
 
-	for (i = 0; i < group->num_ranges; i++) {
-		if (group->ranges[i].low <= value && value <= group->ranges[i].high) {
-			return Resolve(group->ranges[i].group, object);
+	for (i = 0; i < this->num_ranges; i++) {
+		if (this->ranges[i].low <= value && value <= this->ranges[i].high) {
+			return SpriteGroup::Resolve(this->ranges[i].group, object);
 		}
 	}
 
-	return Resolve(group->default_group, object);
+	return SpriteGroup::Resolve(this->default_group, object);
 }
 
 
-static inline const SpriteGroup *ResolveRandom(const RandomizedSpriteGroup *group, ResolverObject *object)
+const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject *object) const
 {
 	uint32 mask;
 	byte index;
 
-	object->scope = group->var_scope;
-	object->count = group->count;
+	object->scope = this->var_scope;
+	object->count = this->count;
 
 	if (object->trigger != 0) {
 		/* Handle triggers */
 		/* Magic code that may or may not do the right things... */
 		byte waiting_triggers = object->GetTriggers(object);
-		byte match = group->triggers & (waiting_triggers | object->trigger);
-		bool res = (group->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == group->triggers);
+		byte match = this->triggers & (waiting_triggers | object->trigger);
+		bool res = (this->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == this->triggers);
 
 		if (res) {
 			waiting_triggers &= ~match;
-			object->reseed |= (group->num_groups - 1) << group->lowest_randbit;
+			object->reseed |= (this->num_groups - 1) << this->lowest_randbit;
 		} else {
 			waiting_triggers |= object->trigger;
 		}
@@ -207,23 +207,14 @@
 		object->SetTriggers(object, waiting_triggers);
 	}
 
-	mask  = (group->num_groups - 1) << group->lowest_randbit;
-	index = (object->GetRandomBits(object) & mask) >> group->lowest_randbit;
+	mask  = (this->num_groups - 1) << this->lowest_randbit;
+	index = (object->GetRandomBits(object) & mask) >> this->lowest_randbit;
 
-	return Resolve(group->groups[index], object);
+	return SpriteGroup::Resolve(this->groups[index], object);
 }
 
 
-/* ResolverObject (re)entry point */
-const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
+const SpriteGroup *RealSpriteGroup::Resolve(ResolverObject *object) const
 {
-	/* We're called even if there is no group, so quietly return nothing */
-	if (group == NULL) return NULL;
-
-	switch (group->type) {
-		case SGT_REAL:          return object->ResolveReal(object, (RealSpriteGroup *)group);
-		case SGT_DETERMINISTIC: return ResolveVariable((DeterministicSpriteGroup *)group, object);
-		case SGT_RANDOMIZED:    return ResolveRandom((RandomizedSpriteGroup *)group, object);
-		default:                return group;
-	}
+	return object->ResolveReal(object, this);
 }
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -50,6 +50,8 @@
 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
 protected:
 	SpriteGroup(SpriteGroupType type) : type(type) {}
+	/** Base sprite group resolver */
+	virtual const SpriteGroup *Resolve(struct ResolverObject *object) const { return this; };
 
 public:
 	virtual ~SpriteGroup() {}
@@ -59,6 +61,20 @@
 	virtual SpriteID GetResult() const { return 0; }
 	virtual byte GetNumResults() const { return 0; }
 	virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
+
+	/**
+	 * ResolverObject (re)entry point.
+	 * This cannot be made a call to a virtual function because virtual functions
+	 * do not like NULL and checking for NULL *everywhere* is more cumbersome than
+	 * this little helper function.
+	 * @param group the group to resolve for
+	 * @param object information needed to resolve the group
+	 * @return the resolved group
+	 */
+	static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
+	{
+		return group == NULL ? NULL : group->Resolve(object);
+	}
 };
 
 
@@ -79,6 +95,9 @@
 	byte num_loading;      ///< Number of loading groups
 	const SpriteGroup **loaded;  ///< List of loaded groups (can be SpriteIDs or Callback results)
 	const SpriteGroup **loading; ///< List of loading groups (can be SpriteIDs or Callback results)
+
+protected:
+	const SpriteGroup *Resolve(ResolverObject *object) const;
 };
 
 /* Shared by deterministic and random groups. */
@@ -159,6 +178,9 @@
 
 	/* Dynamically allocated, this is the sole owner */
 	const SpriteGroup *default_group;
+
+protected:
+	const SpriteGroup *Resolve(ResolverObject *object) const;
 };
 
 enum RandomizedSpriteGroupCompareMode {
@@ -180,6 +202,9 @@
 	byte num_groups; ///< must be power of 2
 
 	const SpriteGroup **groups; ///< Take the group with appropriate index:
+
+protected:
+	const SpriteGroup *Resolve(ResolverObject *object) const;
 };
 
 
@@ -316,9 +341,4 @@
 	ResolverObject() : procedure_call(false) { }
 };
 
-
-/* Base sprite group resolver */
-const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object);
-
-
 #endif /* NEWGRF_SPRITEGROUP_H */
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -633,7 +633,7 @@
 	/* Invalidate all cached vars */
 	_svc.valid = 0;
 
-	return Resolve(group, object);
+	return SpriteGroup::Resolve(group, object);
 }
 
 SpriteID GetCustomStationRelocation(const StationSpec *statspec, const Station *st, TileIndex tile)