mirror of https://github.com/OpenTTD/OpenTTD
(svn r27989) -Fix (r27985): VA2 optimisation failed in various special cases:
- nvar=0 is meant to return the calculated result. - Missing references resolve to NULL and got identified with the default result. - Missing 'break' broke overlapping cases. - Splitting into non-overlapping cases could result in more than 256 cases.release/1.8
parent
c6eb633d18
commit
55a503e6f2
|
@ -4698,6 +4698,8 @@ static void NewSpriteGroup(ByteReader *buf)
|
|||
|
||||
group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
|
||||
group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
|
||||
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
||||
group->calculated_result = ranges.size() == 0;
|
||||
|
||||
/* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
|
||||
std::vector<uint32> bounds;
|
||||
|
@ -4711,10 +4713,11 @@ static void NewSpriteGroup(ByteReader *buf)
|
|||
std::vector<const SpriteGroup *> target;
|
||||
for (uint j = 0; j < bounds.size(); ++j) {
|
||||
uint32 v = bounds[j];
|
||||
const SpriteGroup *t = NULL;
|
||||
const SpriteGroup *t = group->default_group;
|
||||
for (uint i = 0; i < ranges.size(); i++) {
|
||||
if (ranges[i].low <= v && v <= ranges[i].high) {
|
||||
t = ranges[i].group;
|
||||
break;
|
||||
}
|
||||
}
|
||||
target.push_back(t);
|
||||
|
@ -4723,7 +4726,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
|||
|
||||
std::vector<DeterministicSpriteGroupRange> optimised;
|
||||
for (uint j = 0; j < bounds.size(); ) {
|
||||
if (target[j]) {
|
||||
if (target[j] != group->default_group) {
|
||||
DeterministicSpriteGroupRange r;
|
||||
r.group = target[j];
|
||||
r.low = bounds[j];
|
||||
|
|
|
@ -252,7 +252,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
|||
|
||||
object.last_value = last_value;
|
||||
|
||||
if (this->num_ranges == 0) {
|
||||
if (this->calculated_result) {
|
||||
/* 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, true);
|
||||
|
|
|
@ -174,7 +174,8 @@ struct DeterministicSpriteGroup : SpriteGroup {
|
|||
VarSpriteGroupScope var_scope;
|
||||
DeterministicSpriteGroupSize size;
|
||||
uint num_adjusts;
|
||||
byte num_ranges;
|
||||
uint num_ranges;
|
||||
bool calculated_result;
|
||||
DeterministicSpriteGroupAdjust *adjusts;
|
||||
DeterministicSpriteGroupRange *ranges; // Dynamically allocated
|
||||
|
||||
|
|
Loading…
Reference in New Issue