(svn r12352) -Fix: Some callback-results were treated as 8 bit, when they were 15 bit, and vice versa.
authorfrosch
Mon, 10 Mar 2008 15:31:07 +0000
changeset 9181 b65dd02939dd
parent 9180 f39e3460f0ab
child 9182 3c6eb660d4e5
(svn r12352) -Fix: Some callback-results were treated as 8 bit, when they were 15 bit, and vice versa.
Var 0x7E procedure-results are always 15 bit.
Callbacks 0x2A, 0x2C, 0x36 (sometimes), 0x39 and 0x145 are 15 bit.
Non-varaction2-calculated callback-results are also affected by the 8bit masking.
src/newgrf_callbacks.h
src/newgrf_spritegroup.cpp
src/newgrf_spritegroup.h
--- a/src/newgrf_callbacks.h	Sat Mar 08 18:32:01 2008 +0000
+++ b/src/newgrf_callbacks.h	Mon Mar 10 15:31:07 2008 +0000
@@ -210,6 +210,11 @@
 
 	/** Customize the output cargo types of a newly build industry. */
 	CBID_INDUSTRY_OUTPUT_CARGO_TYPES     = 0x14C,
+
+	/* ATTENTION:
+	 * When adding new callbacks and their result is 15bit, add them to newgrf_spritegroup.cpp:Is8BitCallback().
+	 * It does not harm to add them there though they are not implemented. But it does harm if they get forgotton.
+	 */
 };
 
 /**
--- a/src/newgrf_spritegroup.cpp	Sat Mar 08 18:32:01 2008 +0000
+++ b/src/newgrf_spritegroup.cpp	Mon Mar 10 15:31:07 2008 +0000
@@ -80,6 +80,35 @@
 TemporaryStorageArray<uint32, 0x110> _temp_store;
 
 
+static inline bool Is8BitCallback(const ResolverObject *object)
+{
+	/* Var 0x7E procedure results are always 15 bit */
+	if (object == NULL | object->procedure_call) return false;
+
+	switch (object->callback) {
+		/* All these functions are 15 bit callbacks */
+		case CBID_VEHICLE_REFIT_CAPACITY:
+		case CBID_HOUSE_COLOUR:
+		case CBID_HOUSE_CARGO_ACCEPTANCE:
+		case CBID_INDUSTRY_LOCATION:
+		case CBID_HOUSE_ACCEPT_CARGO:
+		case CBID_INDTILE_CARGO_ACCEPTANCE:
+		case CBID_INDTILE_ACCEPT_CARGO:
+		case CBID_VEHICLE_COLOUR_MAPPING:
+		case CBID_HOUSE_PRODUCE_CARGO:
+		case CBID_VEHICLE_SOUND_EFFECT:
+		case CBID_VEHICLE_MODIFY_PROPERTY: // depends on queried property
+		case CBID_CARGO_PROFIT_CALC:
+		case CBID_SOUNDS_AMBIENT_EFFECT:
+		case CBID_CARGO_STATION_RATING_CALC:
+			return false;
+
+		/* The rest is a 8 bit callback, which should be truncated properly */
+		default:
+			return true;
+	}
+}
+
 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 {
 	/* First handle variables common with Action7/9/D */
@@ -174,6 +203,7 @@
 		bool available = true;
 		if (adjust->variable == 0x7E) {
 			ResolverObject subobject = *object;
+			subobject.procedure_call = true;
 			const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject);
 			if (subgroup == NULL || subgroup->type != SGT_CALLBACK) {
 				value = CALLBACK_FAILED;
@@ -204,25 +234,7 @@
 	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;
-		switch (object->callback) {
-			/* All these functions are 15 bit callbacks */
-			case CBID_VEHICLE_REFIT_CAPACITY:
-			case CBID_HOUSE_COLOUR:
-			case CBID_HOUSE_CARGO_ACCEPTANCE:
-			case CBID_INDUSTRY_LOCATION:
-			case CBID_INDTILE_CARGO_ACCEPTANCE:
-			case CBID_VEHICLE_COLOUR_MAPPING:
-			case CBID_HOUSE_PRODUCE_CARGO:
-			case CBID_VEHICLE_SOUND_EFFECT:
-			case CBID_SOUNDS_AMBIENT_EFFECT:
-				nvarzero.g.callback.result = GB(value, 0, 15);
-				break;
-
-			/* The rest is a 8 bit callback, which should be truncated properly */
-			default:
-				nvarzero.g.callback.result = GB(value, 0, 8);
-				break;
-		}
+		nvarzero.g.callback.result = GB(value, 0, Is8BitCallback(object) ? 8 : 15);
 		return &nvarzero;
 	}
 
@@ -280,6 +292,14 @@
 		case SGT_REAL:          return object->ResolveReal(object, group);
 		case SGT_DETERMINISTIC: return ResolveVariable(group, object);
 		case SGT_RANDOMIZED:    return ResolveRandom(group, object);
+		case SGT_CALLBACK: {
+			if (!Is8BitCallback(object)) return group;
+
+			static SpriteGroup result8bit;
+			result8bit.type = SGT_CALLBACK;
+			result8bit.g.callback.result = GB(group->g.callback.result, 0, 8);
+			return &result8bit;
+		}
 		default:                return group;
 	}
 }
--- a/src/newgrf_spritegroup.h	Sat Mar 08 18:32:01 2008 +0000
+++ b/src/newgrf_spritegroup.h	Mon Mar 10 15:31:07 2008 +0000
@@ -198,6 +198,7 @@
 	CallbackID callback;
 	uint32 callback_param1;
 	uint32 callback_param2;
+	bool procedure_call; ///< true if we are currently resolving a var 0x7E procedure result.
 
 	byte trigger;
 	uint32 last_value;
@@ -254,6 +255,8 @@
 	void (*SetTriggers)(const struct ResolverObject*, int);
 	uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
 	const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
+
+	ResolverObject() : procedure_call(false) { }
 };