mirror of https://github.com/OpenTTD/OpenTTD.git
(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.
This commit is contained in:
parent
220b2a1ae1
commit
51bbf0c84f
|
@ -210,6 +210,11 @@ enum CallbackID {
|
||||||
|
|
||||||
/** Customize the output cargo types of a newly build industry. */
|
/** Customize the output cargo types of a newly build industry. */
|
||||||
CBID_INDUSTRY_OUTPUT_CARGO_TYPES = 0x14C,
|
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.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -80,6 +80,35 @@ void InitializeSpriteGroupPool()
|
||||||
TemporaryStorageArray<uint32, 0x110> _temp_store;
|
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)
|
static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||||
{
|
{
|
||||||
/* First handle variables common with Action7/9/D */
|
/* First handle variables common with Action7/9/D */
|
||||||
|
@ -174,6 +203,7 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol
|
||||||
bool available = true;
|
bool available = true;
|
||||||
if (adjust->variable == 0x7E) {
|
if (adjust->variable == 0x7E) {
|
||||||
ResolverObject subobject = *object;
|
ResolverObject subobject = *object;
|
||||||
|
subobject.procedure_call = true;
|
||||||
const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject);
|
const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject);
|
||||||
if (subgroup == NULL || subgroup->type != SGT_CALLBACK) {
|
if (subgroup == NULL || subgroup->type != SGT_CALLBACK) {
|
||||||
value = CALLBACK_FAILED;
|
value = CALLBACK_FAILED;
|
||||||
|
@ -204,25 +234,7 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol
|
||||||
if (group->g.determ.num_ranges == 0) {
|
if (group->g.determ.num_ranges == 0) {
|
||||||
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
||||||
nvarzero.type = SGT_CALLBACK;
|
nvarzero.type = SGT_CALLBACK;
|
||||||
switch (object->callback) {
|
nvarzero.g.callback.result = GB(value, 0, Is8BitCallback(object) ? 8 : 15);
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
return &nvarzero;
|
return &nvarzero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +292,14 @@ const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
|
||||||
case SGT_REAL: return object->ResolveReal(object, group);
|
case SGT_REAL: return object->ResolveReal(object, group);
|
||||||
case SGT_DETERMINISTIC: return ResolveVariable(group, object);
|
case SGT_DETERMINISTIC: return ResolveVariable(group, object);
|
||||||
case SGT_RANDOMIZED: return ResolveRandom(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;
|
default: return group;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,7 @@ struct ResolverObject {
|
||||||
CallbackID callback;
|
CallbackID callback;
|
||||||
uint32 callback_param1;
|
uint32 callback_param1;
|
||||||
uint32 callback_param2;
|
uint32 callback_param2;
|
||||||
|
bool procedure_call; ///< true if we are currently resolving a var 0x7E procedure result.
|
||||||
|
|
||||||
byte trigger;
|
byte trigger;
|
||||||
uint32 last_value;
|
uint32 last_value;
|
||||||
|
@ -254,6 +255,8 @@ struct ResolverObject {
|
||||||
void (*SetTriggers)(const struct ResolverObject*, int);
|
void (*SetTriggers)(const struct ResolverObject*, int);
|
||||||
uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
|
uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
|
||||||
const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
|
const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*);
|
||||||
|
|
||||||
|
ResolverObject() : procedure_call(false) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue