Changeset - r22761:4149c4b18e24
[Not reviewed]
master
0 3 0
frosch - 6 years ago 2018-03-11 15:08:51
frosch@openttd.org
(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.
3 files changed with 8 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/newgrf.cpp
Show inline comments
 
@@ -4698,6 +4698,8 @@ static void NewSpriteGroup(ByteReader *b
 

	
 
			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 *b
 
			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 *b
 

	
 
			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];
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -252,7 +252,7 @@ const SpriteGroup *DeterministicSpriteGr
 

	
 
	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);
src/newgrf_spritegroup.h
Show inline comments
 
@@ -174,7 +174,8 @@ struct DeterministicSpriteGroup : Sprite
 
	VarSpriteGroupScope var_scope;
 
	DeterministicSpriteGroupSize size;
 
	uint num_adjusts;
 
	byte num_ranges;
 
	uint num_ranges;
 
	bool calculated_result;
 
	DeterministicSpriteGroupAdjust *adjusts;
 
	DeterministicSpriteGroupRange *ranges; // Dynamically allocated
 

	
0 comments (0 inline, 0 general)