newgrf_spritegroup.c
changeset 3893 ced26054ee00
parent 3861 6a7694fa2b06
child 3942 718fa406d7eb
equal deleted inserted replaced
3892:721543bd8d79 3893:ced26054ee00
    68 
    68 
    69 	_spritegroup_count = 0;
    69 	_spritegroup_count = 0;
    70 }
    70 }
    71 
    71 
    72 
    72 
    73 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter)
    73 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
    74 {
    74 {
    75 	/* Return common variables */
    75 	/* Return common variables */
    76 	switch (variable) {
    76 	switch (variable) {
    77 		case 0x00: return _date;
    77 		case 0x00: return _date;
    78 		case 0x01: return _cur_year;
    78 		case 0x01: return _cur_year;
    88 		case 0x1B: return GB(_display_opt, 0, 6);
    88 		case 0x1B: return GB(_display_opt, 0, 6);
    89 		case 0x1C: return object->last_value;
    89 		case 0x1C: return object->last_value;
    90 		case 0x20: return _opt.landscape == LT_HILLY ? _opt.snow_line : 0xFF;
    90 		case 0x20: return _opt.landscape == LT_HILLY ? _opt.snow_line : 0xFF;
    91 
    91 
    92 		/* Not a common variable, so evalute the feature specific variables */
    92 		/* Not a common variable, so evalute the feature specific variables */
    93 		default: return object->GetVariable(object, variable, parameter);
    93 		default: return object->GetVariable(object, variable, parameter, available);
    94 	}
    94 	}
    95 }
    95 }
    96 
    96 
    97 
    97 
    98 /* Evaluate an adjustment for a variable of the given size. This is a bit of
    98 /* Evaluate an adjustment for a variable of the given size. This is a bit of
   140 
   140 
   141 
   141 
   142 static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, ResolverObject *object)
   142 static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, ResolverObject *object)
   143 {
   143 {
   144 	static SpriteGroup nvarzero;
   144 	static SpriteGroup nvarzero;
   145 	const SpriteGroup *target;
       
   146 	int32 last_value = object->last_value;
   145 	int32 last_value = object->last_value;
   147 	int32 value = -1;
   146 	int32 value = -1;
   148 	uint i;
   147 	uint i;
   149 
   148 
   150 	object->scope = group->g.determ.var_scope;
   149 	object->scope = group->g.determ.var_scope;
   151 
   150 
   152 	for (i = 0; i < group->g.determ.num_adjusts; i++) {
   151 	for (i = 0; i < group->g.determ.num_adjusts; i++) {
   153 		DeterministicSpriteGroupAdjust *adjust = &group->g.determ.adjusts[i];
   152 		DeterministicSpriteGroupAdjust *adjust = &group->g.determ.adjusts[i];
   154 		value = GetVariable(object, adjust->variable, adjust->parameter);
   153 
       
   154 		/* Try to get the variable. We shall assume it is available, unless told otherwise. */
       
   155 		bool available = true;
       
   156 		value = GetVariable(object, adjust->variable, adjust->parameter, &available);
       
   157 
       
   158 		if (!available) {
       
   159 			/* Unsupported property: skip further processing and return either
       
   160 			 * the group from the first range or the default group. */
       
   161 			return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object);
       
   162 		}
       
   163 
   155 		switch (group->g.determ.size) {
   164 		switch (group->g.determ.size) {
   156 			case DSG_SIZE_BYTE:  value = EvalAdjust_int8(adjust, last_value, value); break;
   165 			case DSG_SIZE_BYTE:  value = EvalAdjust_int8(adjust, last_value, value); break;
   157 			case DSG_SIZE_WORD:  value = EvalAdjust_int16(adjust, last_value, value); break;
   166 			case DSG_SIZE_WORD:  value = EvalAdjust_int16(adjust, last_value, value); break;
   158 			case DSG_SIZE_DWORD: value = EvalAdjust_int32(adjust, last_value, value); break;
   167 			case DSG_SIZE_DWORD: value = EvalAdjust_int32(adjust, last_value, value); break;
   159 			default: NOT_REACHED(); break;
   168 			default: NOT_REACHED(); break;
   160 		}
   169 		}
   161 		last_value = value;
   170 		last_value = value;
   162 	}
   171 	}
   163 
   172 
   164 	if (value == -1) {
   173 	if (group->g.determ.num_ranges == 0) {
   165 		/* Unsupported property */
   174 		/* nvar == 0 is a special case -- we turn our value into a callback result */
   166 		target = group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group;
   175 		nvarzero.type = SGT_CALLBACK;
   167 	} else {
   176 		nvarzero.g.callback.result = GB(value, 0, 15) | 0x8000;
   168 		if (group->g.determ.num_ranges == 0) {
   177 		return &nvarzero;
   169 			/* nvar == 0 is a special case -- we turn our value into a callback result */
   178 	}
   170 			nvarzero.type = SGT_CALLBACK;
   179 
   171 			nvarzero.g.callback.result = GB(value, 0, 15) | 0x8000;
   180 	for (i = 0; i < group->g.determ.num_ranges; i++) {
   172 			return &nvarzero;
   181 		if (group->g.determ.ranges[i].low <= (uint32)value && (uint32)value <= group->g.determ.ranges[i].high) {
   173 		}
   182 			return Resolve(group->g.determ.ranges[i].group, object);
   174 
   183 		}
   175 		target = group->g.determ.default_group;
   184 	}
   176 		for (i = 0; i < group->g.determ.num_ranges; i++) {
   185 
   177 			if (group->g.determ.ranges[i].low <= (uint32)value && (uint32)value <= group->g.determ.ranges[i].high) {
   186 	return Resolve(group->g.determ.default_group, object);
   178 				target = group->g.determ.ranges[i].group;
       
   179 				break;
       
   180 			}
       
   181 		}
       
   182 	}
       
   183 
       
   184 	return Resolve(target, object);
       
   185 }
   187 }
   186 
   188 
   187 
   189 
   188 static inline const SpriteGroup *ResolveRandom(const SpriteGroup *group, ResolverObject *object)
   190 static inline const SpriteGroup *ResolveRandom(const SpriteGroup *group, ResolverObject *object)
   189 {
   191 {