changeset 3893:bbd2b62cf76e draft

(svn r4960) - NewGRF: explicitly handle unsupported variables, instead of returning -1.
author peter1138 <peter1138@openttd.org>
date Tue, 23 May 2006 19:36:50 +0000
parents 3d390604a45e
children 7fa0a531e862
files newgrf_engine.c newgrf_spritegroup.c newgrf_spritegroup.h newgrf_station.c
diffstat 4 files changed, 34 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/newgrf_engine.c
+++ b/newgrf_engine.c
@@ -476,7 +476,7 @@
 }
 
 
-static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter)
+static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
 	const Vehicle *v = GRV(object);
 
@@ -487,8 +487,10 @@
 			case 0x46: return 0;               /* Motion counter */
 			case 0xC4: return _cur_year;       /* Build year */
 			case 0xDA: return INVALID_VEHICLE; /* Next vehicle */
-			default:   return -1;
 		}
+
+		*available = false;
+		return -1;
 	}
 
 	/* Calculated vehicle parameters */
@@ -719,6 +721,7 @@
 
 	DEBUG(grf, 1)("Unhandled vehicle property 0x%X, type 0x%X", variable, v->type);
 
+	*available = false;
 	return -1;
 }
 
--- a/newgrf_spritegroup.c
+++ b/newgrf_spritegroup.c
@@ -70,7 +70,7 @@
 }
 
 
-static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter)
+static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
 	/* Return common variables */
 	switch (variable) {
@@ -90,7 +90,7 @@
 		case 0x20: return _opt.landscape == LT_HILLY ? _opt.snow_line : 0xFF;
 
 		/* Not a common variable, so evalute the feature specific variables */
-		default: return object->GetVariable(object, variable, parameter);
+		default: return object->GetVariable(object, variable, parameter, available);
 	}
 }
 
@@ -142,7 +142,6 @@
 static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, ResolverObject *object)
 {
 	static SpriteGroup nvarzero;
-	const SpriteGroup *target;
 	int32 last_value = object->last_value;
 	int32 value = -1;
 	uint i;
@@ -151,7 +150,17 @@
 
 	for (i = 0; i < group->g.determ.num_adjusts; i++) {
 		DeterministicSpriteGroupAdjust *adjust = &group->g.determ.adjusts[i];
-		value = GetVariable(object, adjust->variable, adjust->parameter);
+
+		/* Try to get the variable. We shall assume it is available, unless told otherwise. */
+		bool available = true;
+		value = GetVariable(object, adjust->variable, adjust->parameter, &available);
+
+		if (!available) {
+			/* Unsupported property: skip further processing and return either
+			 * the group from the first range or the default group. */
+			return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object);
+		}
+
 		switch (group->g.determ.size) {
 			case DSG_SIZE_BYTE:  value = EvalAdjust_int8(adjust, last_value, value); break;
 			case DSG_SIZE_WORD:  value = EvalAdjust_int16(adjust, last_value, value); break;
@@ -161,27 +170,20 @@
 		last_value = value;
 	}
 
-	if (value == -1) {
-		/* Unsupported property */
-		target = group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group;
-	} else {
-		if (group->g.determ.num_ranges == 0) {
-			/* nvar == 0 is a special case -- we turn our value into a callback result */
-			nvarzero.type = SGT_CALLBACK;
-			nvarzero.g.callback.result = GB(value, 0, 15) | 0x8000;
-			return &nvarzero;
-		}
+	if (group->g.determ.num_ranges == 0) {
+		/* nvar == 0 is a special case -- we turn our value into a callback result */
+		nvarzero.type = SGT_CALLBACK;
+		nvarzero.g.callback.result = GB(value, 0, 15) | 0x8000;
+		return &nvarzero;
+	}
 
-		target = group->g.determ.default_group;
-		for (i = 0; i < group->g.determ.num_ranges; i++) {
-			if (group->g.determ.ranges[i].low <= (uint32)value && (uint32)value <= group->g.determ.ranges[i].high) {
-				target = group->g.determ.ranges[i].group;
-				break;
-			}
+	for (i = 0; i < group->g.determ.num_ranges; i++) {
+		if (group->g.determ.ranges[i].low <= (uint32)value && (uint32)value <= group->g.determ.ranges[i].high) {
+			return Resolve(group->g.determ.ranges[i].group, object);
 		}
 	}
 
-	return Resolve(target, object);
+	return Resolve(group->g.determ.default_group, object);
 }
 
 
--- a/newgrf_spritegroup.h
+++ b/newgrf_spritegroup.h
@@ -180,7 +180,7 @@
 	uint32 (*GetRandomBits)(const struct ResolverObject*);
 	uint32 (*GetTriggers)(const struct ResolverObject*);
 	void (*SetTriggers)(const struct ResolverObject*, int);
-	uint32 (*GetVariable)(const struct ResolverObject*, byte, byte);
+	uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
 	const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
 } ResolverObject;
 
--- a/newgrf_station.c
+++ b/newgrf_station.c
@@ -309,7 +309,7 @@
 }
 
 
-static uint32 StationGetVariable(const ResolverObject *object, byte variable, byte parameter)
+static uint32 StationGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
 	const Station *st = object->u.station.st;
 	TileIndex tile = object->u.station.tile;
@@ -326,8 +326,10 @@
 			case 0x43: return _current_player; /* Station owner */
 			case 0x44: return 2;               /* PBS status */
 			case 0xFA: return _date;           /* Build date */
-			default:   return -1;
 		}
+
+		*available = false;
+		return -1;
 	}
 
 	switch (variable) {
@@ -390,6 +392,7 @@
 
 	DEBUG(grf, 1)("Unhandled station property 0x%X", variable);
 
+	*available = false;
 	return -1;
 }