From 51bbf0c84fb9f34317b9f1d7e724ef8cd40aadee Mon Sep 17 00:00:00 2001 From: frosch Date: Mon, 10 Mar 2008 15:31:07 +0000 Subject: [PATCH] (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 | 5 ++++ src/newgrf_spritegroup.cpp | 58 +++++++++++++++++++++++++------------- src/newgrf_spritegroup.h | 3 ++ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/src/newgrf_callbacks.h b/src/newgrf_callbacks.h index b21b29f8e9..40e10694c5 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.h @@ -210,6 +210,11 @@ enum CallbackID { /** 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. + */ }; /** diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 376078cada..b64c784b33 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -80,6 +80,35 @@ void InitializeSpriteGroupPool() TemporaryStorageArray _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 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol 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 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol 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 @@ const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object) 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; } } diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index f6507b4d28..4a3baa0f4e 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -198,6 +198,7 @@ struct ResolverObject { 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 @@ struct ResolverObject { 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) { } };