@@ -118,24 +118,29 @@ constexpr auto rotation_to_similar_array = map(rotation_to_similar_, iota_array<
118
118
119
119
constexpr std::array<rotation, 3 > rotation_to_similar (rotation r)
120
120
{
121
- CORRADE_ASSUME (r < rotation_COUNT);
122
121
return rotation_to_similar_array.data ()[(uint8_t )r];
123
122
}
124
123
125
- template <rotation r> constexpr uint8_t get_length_axis ( )
124
+ constexpr uint8_t get_length_axisʹ(rotation r )
126
125
{
127
- static_assert ((int )r % 2 == 0 );
128
126
using enum rotation;
129
- if constexpr (r == N || r == S)
127
+ if (r == N || r == S)
130
128
return 1 ;
131
- else if constexpr (r == W || r == E)
129
+ else if (r == W || r == E)
132
130
return 0 ;
133
- fm_assert (false );
131
+ else
132
+ return 0 ; // garbage in, garbage out
133
+ }
134
+
135
+ constexpr uint8_t get_length_axis (rotation r)
136
+ {
137
+ constexpr auto table = map (get_length_axisʹ, iota_array<rotation, (size_t )rotation_COUNT>);
138
+ return table.data ()[(size_t )r];
134
139
}
135
140
136
141
template <bool MultiStep>
137
142
CORRADE_NEVER_INLINE
138
- bool update_movement_body (size_t & i, critter& C, const anim_def& info, uint8_t nsteps, rotation new_r)
143
+ bool update_movement_body (size_t & i, critter& C, const anim_def& info, uint8_t nsteps, rotation new_r, rotation visible_r )
139
144
{
140
145
const auto vec = rotation_to_vec (new_r);
141
146
using Frac = decltype (critter::offset_frac);
@@ -156,7 +161,7 @@ bool update_movement_body(size_t& i, critter& C, const anim_def& info, uint8_t n
156
161
C.offset_frac = Frac (rem * frac);
157
162
if (C.can_move_to (off_i))
158
163
{
159
- C.move_to (i, off_i, new_r );
164
+ C.move_to (i, off_i, visible_r );
160
165
if constexpr (MultiStep)
161
166
(C.frame += nsteps) %= info.nframes ;
162
167
else
@@ -173,64 +178,60 @@ bool update_movement_body(size_t& i, critter& C, const anim_def& info, uint8_t n
173
178
return false ;
174
179
}
175
180
176
- template <rotation r>
177
- CORRADE_ALWAYS_INLINE
178
- bool update_movement_3way (size_t & i, critter& C, const anim_def& info)
181
+ bool update_movement_3way (size_t & i, critter& C, const anim_def& info, rotation new_r)
179
182
{
180
- constexpr auto rotations = rotation_to_similar (r );
181
- if (update_movement_body<false >(i, C, info, 0 , rotations[0 ]))
183
+ const auto rotations = rotation_to_similar (new_r );
184
+ if (update_movement_body<false >(i, C, info, 0 , rotations. data () [0 ], new_r ))
182
185
return true ;
183
- if (update_movement_body<false >(i, C, info, 0 , rotations[1 ]))
186
+ if (update_movement_body<false >(i, C, info, 0 , rotations. data () [1 ], new_r ))
184
187
return true ;
185
- if (update_movement_body<false >(i, C, info, 0 , rotations[2 ]))
188
+ if (update_movement_body<false >(i, C, info, 0 , rotations. data () [2 ], new_r ))
186
189
return true ;
187
190
return false ;
188
191
}
189
192
190
193
constexpr bool DoUnroll = true ;
191
194
192
- template <rotation new_r>
193
- requires ((int )new_r % 2 != 0 )
194
- CORRADE_ALWAYS_INLINE
195
- bool update_movement_1 (critter& C, size_t & i, const anim_def& info, uint32_t nframes)
195
+ template <bool IsEven>
196
+ requires (!IsEven)
197
+ bool update_movement_1 (critter& C, size_t & i, const anim_def& info, uint32_t nframes, rotation new_r)
196
198
{
199
+ // Debug{} << "< nframes" << nframes;
197
200
if constexpr (DoUnroll)
198
201
{
199
- // Debug{} << "< nframes" << nframes;
200
202
while (nframes > 1 )
201
203
{
202
204
auto len = (uint8_t )Math::min (nframes, (uint32_t )C.bbox_size .min ());
203
205
if (len <= 1 )
204
206
break ;
205
- if (!update_movement_body<true >(i, C, info, len, new_r))
207
+ if (!update_movement_body<true >(i, C, info, len, new_r, new_r ))
206
208
break ;
207
209
// Debug{} << " " << len;
208
210
nframes -= len;
209
211
}
210
- // Debug{} << ">" << nframes;
211
212
}
213
+ // Debug{} << ">" << nframes;
212
214
213
215
for (auto k = 0u ; k < nframes; k++)
214
- if (!update_movement_3way<new_r> (i, C, info))
216
+ if (!update_movement_3way (i, C, info, new_r ))
215
217
return false ;
216
218
return true ;
217
219
}
218
220
219
- template <rotation new_r>
220
- requires ((int )new_r % 2 == 0 )
221
- CORRADE_ALWAYS_INLINE
222
- bool update_movement_1 (critter& C, size_t & i, const anim_def& info, uint32_t nframes)
221
+ template <bool IsEven>
222
+ requires IsEven
223
+ bool update_movement_1 (critter& C, size_t & i, const anim_def& info, uint32_t nframes, rotation new_r)
223
224
{
224
225
if constexpr (DoUnroll)
225
226
{
226
227
// Debug{} << "< nframes" << nframes;
227
228
while (nframes > 1 )
228
229
{
229
- constexpr auto len_axis = get_length_axis<new_r>( );
230
+ const auto len_axis = get_length_axis (new_r );
230
231
auto len = (uint8_t )Math::min (nframes, (uint32_t )C.bbox_size .data ()[len_axis]);
231
232
if (len <= 1 ) [[unlikely]]
232
233
break ;
233
- if (!update_movement_body<true >(i, C, info, len, new_r))
234
+ if (!update_movement_body<true >(i, C, info, len, new_r, new_r ))
234
235
break ;
235
236
// Debug{} << " " << len;
236
237
nframes -= len;
@@ -239,20 +240,11 @@ bool update_movement_1(critter& C, size_t& i, const anim_def& info, uint32_t nfr
239
240
}
240
241
241
242
for (auto k = 0u ; k < nframes; k++)
242
- if (!update_movement_body<false >(i, C, info, 0 , new_r))
243
+ if (!update_movement_body<false >(i, C, info, 0 , new_r, new_r ))
243
244
return false ;
244
245
return true ;
245
246
}
246
247
247
- template bool update_movement_1<(rotation)0 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
248
- template bool update_movement_1<(rotation)1 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
249
- template bool update_movement_1<(rotation)2 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
250
- template bool update_movement_1<(rotation)3 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
251
- template bool update_movement_1<(rotation)4 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
252
- template bool update_movement_1<(rotation)5 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
253
- template bool update_movement_1<(rotation)6 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
254
- template bool update_movement_1<(rotation)7 >(critter& C, size_t & i, const anim_def& info, uint32_t nframes);
255
-
256
248
struct step_s
257
249
{
258
250
uint32_t count;
@@ -441,15 +433,12 @@ void critter::update_movement(size_t& i, const Ns& dt, rotation new_r)
441
433
442
434
switch (new_r)
443
435
{
436
+ using enum rotation;
444
437
default : std::unreachable ();
445
- case (rotation)0 : ret = update_movement_1<(rotation)0 >(*this , i, info, nframes); break ;
446
- case (rotation)1 : ret = update_movement_1<(rotation)1 >(*this , i, info, nframes); break ;
447
- case (rotation)2 : ret = update_movement_1<(rotation)2 >(*this , i, info, nframes); break ;
448
- case (rotation)3 : ret = update_movement_1<(rotation)3 >(*this , i, info, nframes); break ;
449
- case (rotation)4 : ret = update_movement_1<(rotation)4 >(*this , i, info, nframes); break ;
450
- case (rotation)5 : ret = update_movement_1<(rotation)5 >(*this , i, info, nframes); break ;
451
- case (rotation)6 : ret = update_movement_1<(rotation)6 >(*this , i, info, nframes); break ;
452
- case (rotation)7 : ret = update_movement_1<(rotation)7 >(*this , i, info, nframes); break ;
438
+ case N: case E: case S: case W:
439
+ ret = update_movement_1<true >(*this , i, info, nframes, new_r); break ;
440
+ case NW: case NE: case SE: case SW:
441
+ ret = update_movement_1<false >(*this , i, info, nframes, new_r); break ;
453
442
}
454
443
455
444
if (!ret) [[unlikely]]
0 commit comments