77 _spritegroup_count = 0; |
77 _spritegroup_count = 0; |
78 } |
78 } |
79 |
79 |
80 TemporaryStorageArray<uint32, 0x110> _temp_store; |
80 TemporaryStorageArray<uint32, 0x110> _temp_store; |
81 |
81 |
|
82 |
|
83 static inline bool Is8BitCallback(const ResolverObject *object) |
|
84 { |
|
85 /* Var 0x7E procedure results are always 15 bit */ |
|
86 if (object == NULL || object->procedure_call) return false; |
|
87 |
|
88 switch (object->callback) { |
|
89 /* All these functions are 15 bit callbacks */ |
|
90 case CBID_STATION_SPRITE_LAYOUT: |
|
91 case CBID_VEHICLE_REFIT_CAPACITY: |
|
92 case CBID_HOUSE_COLOUR: |
|
93 case CBID_HOUSE_CARGO_ACCEPTANCE: |
|
94 case CBID_INDUSTRY_LOCATION: |
|
95 case CBID_HOUSE_ACCEPT_CARGO: |
|
96 case CBID_INDTILE_CARGO_ACCEPTANCE: |
|
97 case CBID_INDTILE_ACCEPT_CARGO: |
|
98 case CBID_VEHICLE_COLOUR_MAPPING: |
|
99 case CBID_HOUSE_PRODUCE_CARGO: |
|
100 case CBID_INDTILE_SHAPE_CHECK: // depends on grf version, masked to 8 bit in PerformIndustryTileSlopeCheck() if needed |
|
101 case CBID_VEHICLE_SOUND_EFFECT: |
|
102 case CBID_VEHICLE_MODIFY_PROPERTY: // depends on queried property |
|
103 case CBID_CARGO_PROFIT_CALC: |
|
104 case CBID_SOUNDS_AMBIENT_EFFECT: |
|
105 case CBID_CARGO_STATION_RATING_CALC: |
|
106 return false; |
|
107 |
|
108 /* The rest is a 8 bit callback, which should be truncated properly */ |
|
109 default: |
|
110 return true; |
|
111 } |
|
112 } |
82 |
113 |
83 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) |
114 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) |
84 { |
115 { |
85 /* First handle variables common with Action7/9/D */ |
116 /* First handle variables common with Action7/9/D */ |
86 uint32 value; |
117 uint32 value; |
172 |
203 |
173 /* Try to get the variable. We shall assume it is available, unless told otherwise. */ |
204 /* Try to get the variable. We shall assume it is available, unless told otherwise. */ |
174 bool available = true; |
205 bool available = true; |
175 if (adjust->variable == 0x7E) { |
206 if (adjust->variable == 0x7E) { |
176 ResolverObject subobject = *object; |
207 ResolverObject subobject = *object; |
|
208 subobject.procedure_call = true; |
177 const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject); |
209 const SpriteGroup *subgroup = Resolve(adjust->subroutine, &subobject); |
178 if (subgroup == NULL || subgroup->type != SGT_CALLBACK) { |
210 if (subgroup == NULL || subgroup->type != SGT_CALLBACK) { |
179 value = CALLBACK_FAILED; |
211 value = CALLBACK_FAILED; |
180 } else { |
212 } else { |
181 value = subgroup->g.callback.result; |
213 value = subgroup->g.callback.result; |
202 object->last_value = last_value; |
234 object->last_value = last_value; |
203 |
235 |
204 if (group->g.determ.num_ranges == 0) { |
236 if (group->g.determ.num_ranges == 0) { |
205 /* nvar == 0 is a special case -- we turn our value into a callback result */ |
237 /* nvar == 0 is a special case -- we turn our value into a callback result */ |
206 nvarzero.type = SGT_CALLBACK; |
238 nvarzero.type = SGT_CALLBACK; |
207 switch (object->callback) { |
239 nvarzero.g.callback.result = GB(value, 0, Is8BitCallback(object) ? 8 : 15); |
208 /* All these functions are 15 bit callbacks */ |
|
209 case CBID_VEHICLE_REFIT_CAPACITY: |
|
210 case CBID_HOUSE_COLOUR: |
|
211 case CBID_HOUSE_CARGO_ACCEPTANCE: |
|
212 case CBID_INDUSTRY_LOCATION: |
|
213 case CBID_INDTILE_CARGO_ACCEPTANCE: |
|
214 case CBID_VEHICLE_COLOUR_MAPPING: |
|
215 case CBID_HOUSE_PRODUCE_CARGO: |
|
216 case CBID_VEHICLE_SOUND_EFFECT: |
|
217 case CBID_SOUNDS_AMBIENT_EFFECT: |
|
218 nvarzero.g.callback.result = GB(value, 0, 15); |
|
219 break; |
|
220 |
|
221 /* The rest is a 8 bit callback, which should be truncated properly */ |
|
222 default: |
|
223 nvarzero.g.callback.result = GB(value, 0, 8); |
|
224 break; |
|
225 } |
|
226 return &nvarzero; |
240 return &nvarzero; |
227 } |
241 } |
228 |
242 |
229 for (i = 0; i < group->g.determ.num_ranges; i++) { |
243 for (i = 0; i < group->g.determ.num_ranges; i++) { |
230 if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) { |
244 if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) { |
240 { |
254 { |
241 uint32 mask; |
255 uint32 mask; |
242 byte index; |
256 byte index; |
243 |
257 |
244 object->scope = group->g.random.var_scope; |
258 object->scope = group->g.random.var_scope; |
|
259 object->count = group->g.random.count; |
245 |
260 |
246 if (object->trigger != 0) { |
261 if (object->trigger != 0) { |
247 /* Handle triggers */ |
262 /* Handle triggers */ |
248 /* Magic code that may or may not do the right things... */ |
263 /* Magic code that may or may not do the right things... */ |
249 byte waiting_triggers = object->GetTriggers(object); |
264 byte waiting_triggers = object->GetTriggers(object); |
278 |
293 |
279 switch (group->type) { |
294 switch (group->type) { |
280 case SGT_REAL: return object->ResolveReal(object, group); |
295 case SGT_REAL: return object->ResolveReal(object, group); |
281 case SGT_DETERMINISTIC: return ResolveVariable(group, object); |
296 case SGT_DETERMINISTIC: return ResolveVariable(group, object); |
282 case SGT_RANDOMIZED: return ResolveRandom(group, object); |
297 case SGT_RANDOMIZED: return ResolveRandom(group, object); |
|
298 case SGT_CALLBACK: { |
|
299 if (!Is8BitCallback(object)) return group; |
|
300 |
|
301 static SpriteGroup result8bit; |
|
302 result8bit.type = SGT_CALLBACK; |
|
303 result8bit.g.callback.result = GB(group->g.callback.result, 0, 8); |
|
304 return &result8bit; |
|
305 } |
283 default: return group; |
306 default: return group; |
284 } |
307 } |
285 } |
308 } |