| 213 | } |
| 214 | |
| 215 | u16 easeInOutCubic16(u16 x) { |
| 216 | const u32 MAX = 0xFFFF; // 65535 |
| 217 | const u32 HALF = (MAX + 1) >> 1; // 32768 |
| 218 | const fl::u64 M2 = (fl::u64)MAX * MAX; // 65535² = 4 294 836 225 |
| 219 | |
| 220 | if (x < HALF) { |
| 221 | // first half: y = 4·(x/MAX)³ → y_i = 4·x³ / MAX² |
| 222 | fl::u64 xi = x; |
| 223 | fl::u64 cube = xi * xi * xi; // x³ |
| 224 | // add M2/2 for rounding |
| 225 | fl::u64 num = 4 * cube + (M2 >> 1); |
| 226 | return (u16)(num / M2); |
| 227 | } else { |
| 228 | // second half: y = 1 − ((2·(1−x/MAX))³)/2 |
| 229 | // → y_i = MAX − (4·(MAX−x)³ / MAX²) |
| 230 | fl::u64 d = MAX - x; |
| 231 | fl::u64 cube = d * d * d; // (MAX−x)³ |
| 232 | fl::u64 num = 4 * cube + (M2 >> 1); |
| 233 | return (u16)(MAX - (num / M2)); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | u16 easeOutQuad16(u16 i) { |
| 238 | // ease-out quadratic: 1 - (1-t)² |
no outgoing calls
no test coverage detected