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 { |