74 _SpriteGroup_pool.CleanPool(); |
74 _SpriteGroup_pool.CleanPool(); |
75 |
75 |
76 _spritegroup_count = 0; |
76 _spritegroup_count = 0; |
77 } |
77 } |
78 |
78 |
79 uint32 _temp_store[0x110]; |
79 TemporaryStorageArray<uint32, 0x110> _temp_store; |
80 |
80 |
81 |
81 |
82 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) |
82 static inline uint32 GetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available) |
83 { |
83 { |
84 /* Return common variables */ |
84 /* Return common variables */ |
96 case 0x1A: return UINT_MAX; |
96 case 0x1A: return UINT_MAX; |
97 case 0x1B: return GB(_display_opt, 0, 6); |
97 case 0x1B: return GB(_display_opt, 0, 6); |
98 case 0x1C: return object->last_value; |
98 case 0x1C: return object->last_value; |
99 case 0x20: return _opt.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF; |
99 case 0x20: return _opt.landscape == LT_ARCTIC ? GetSnowLine() : 0xFF; |
100 |
100 |
101 case 0x7D: return _temp_store[parameter]; |
101 case 0x7D: return _temp_store.Get(parameter); |
102 |
102 |
103 /* Not a common variable, so evalute the feature specific variables */ |
103 /* Not a common variable, so evalute the feature specific variables */ |
104 default: return object->GetVariable(object, variable, parameter, available); |
104 default: return object->GetVariable(object, variable, parameter, available); |
105 } |
105 } |
|
106 } |
|
107 |
|
108 |
|
109 /** |
|
110 * Rotate val rot times to the right |
|
111 * @param val the value to rotate |
|
112 * @param rot the amount of times to rotate |
|
113 * @return the rotated value |
|
114 */ |
|
115 static uint32 RotateRight(uint32 val, uint32 rot) |
|
116 { |
|
117 /* Do not rotate more than necessary */ |
|
118 rot %= 32; |
|
119 |
|
120 return (val >> rot) | (val << (32 - rot)); |
106 } |
121 } |
107 |
122 |
108 |
123 |
109 /* Evaluate an adjustment for a variable of the given size. |
124 /* Evaluate an adjustment for a variable of the given size. |
110 * U is the unsigned type and S is the signed type to use. */ |
125 * U is the unsigned type and S is the signed type to use. */ |
111 template <typename U, typename S> |
126 template <typename U, typename S> |
112 static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, U last_value, uint32 value) |
127 static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ResolverObject *object, U last_value, uint32 value) |
113 { |
128 { |
114 value >>= adjust->shift_num; |
129 value >>= adjust->shift_num; |
115 value &= adjust->and_mask; |
130 value &= adjust->and_mask; |
116 |
131 |
117 if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val; |
132 if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val; |
135 case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value; |
150 case DSGA_OP_UMOD: return value == 0 ? (U)last_value : (U)last_value % (U)value; |
136 case DSGA_OP_MUL: return last_value * value; |
151 case DSGA_OP_MUL: return last_value * value; |
137 case DSGA_OP_AND: return last_value & value; |
152 case DSGA_OP_AND: return last_value & value; |
138 case DSGA_OP_OR: return last_value | value; |
153 case DSGA_OP_OR: return last_value | value; |
139 case DSGA_OP_XOR: return last_value ^ value; |
154 case DSGA_OP_XOR: return last_value ^ value; |
140 case DSGA_OP_STO: |
155 case DSGA_OP_STO: _temp_store.Store(value, last_value); return last_value; |
141 if (value < lengthof(_temp_store)) _temp_store[value] = last_value; |
|
142 return last_value; |
|
143 case DSGA_OP_RST: return value; |
156 case DSGA_OP_RST: return value; |
|
157 case DSGA_OP_STOP: if (object->psa != NULL) object->psa->Store(value, last_value); return last_value; |
|
158 case DSGA_OP_ROR: return RotateRight(last_value, value); |
|
159 case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2); |
|
160 case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2); |
144 default: return value; |
161 default: return value; |
145 } |
162 } |
146 } |
163 } |
147 |
164 |
148 |
165 |
177 * the group from the first range or the default group. */ |
194 * the group from the first range or the default group. */ |
178 return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object); |
195 return Resolve(group->g.determ.num_ranges > 0 ? group->g.determ.ranges[0].group : group->g.determ.default_group, object); |
179 } |
196 } |
180 |
197 |
181 switch (group->g.determ.size) { |
198 switch (group->g.determ.size) { |
182 case DSG_SIZE_BYTE: value = EvalAdjustT<uint8, int8>(adjust, last_value, value); break; |
199 case DSG_SIZE_BYTE: value = EvalAdjustT<uint8, int8> (adjust, object, last_value, value); break; |
183 case DSG_SIZE_WORD: value = EvalAdjustT<uint16, int16>(adjust, last_value, value); break; |
200 case DSG_SIZE_WORD: value = EvalAdjustT<uint16, int16>(adjust, object, last_value, value); break; |
184 case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, last_value, value); break; |
201 case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, object, last_value, value); break; |
185 default: NOT_REACHED(); break; |
202 default: NOT_REACHED(); break; |
186 } |
203 } |
187 last_value = value; |
204 last_value = value; |
188 } |
205 } |
189 |
206 |
190 object->last_value = last_value; |
207 object->last_value = last_value; |
191 |
208 |
192 if (group->g.determ.num_ranges == 0) { |
209 if (group->g.determ.num_ranges == 0) { |
193 /* nvar == 0 is a special case -- we turn our value into a callback result */ |
210 /* nvar == 0 is a special case -- we turn our value into a callback result */ |
194 nvarzero.type = SGT_CALLBACK; |
211 nvarzero.type = SGT_CALLBACK; |
195 nvarzero.g.callback.result = GB(value, 0, 15); |
212 switch (object->callback) { |
|
213 /* All these functions are 15 bit callbacks */ |
|
214 case CBID_VEHICLE_REFIT_CAPACITY: |
|
215 case CBID_HOUSE_COLOUR: |
|
216 case CBID_HOUSE_CARGO_ACCEPTANCE: |
|
217 case CBID_INDUSTRY_LOCATION: |
|
218 case CBID_INDTILE_CARGO_ACCEPTANCE: |
|
219 case CBID_VEHICLE_COLOUR_MAPPING: |
|
220 case CBID_HOUSE_PRODUCE_CARGO: |
|
221 case CBID_VEHICLE_SOUND_EFFECT: |
|
222 case CBID_SOUNDS_AMBIENT_EFFECT: |
|
223 nvarzero.g.callback.result = GB(value, 0, 15); |
|
224 break; |
|
225 |
|
226 /* The rest is a 8 bit callback, which should be truncated properly */ |
|
227 default: |
|
228 nvarzero.g.callback.result = GB(value, 0, 8); |
|
229 break; |
|
230 } |
196 return &nvarzero; |
231 return &nvarzero; |
197 } |
232 } |
198 |
233 |
199 for (i = 0; i < group->g.determ.num_ranges; i++) { |
234 for (i = 0; i < group->g.determ.num_ranges; i++) { |
200 if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) { |
235 if (group->g.determ.ranges[i].low <= value && value <= group->g.determ.ranges[i].high) { |