| 272 | } |
| 273 | |
| 274 | u16 easeInSine16(u16 i) { |
| 275 | // ease-in sine: 1 - cos(t * π/2) |
| 276 | // Handle boundary conditions explicitly |
| 277 | if (i == 0) |
| 278 | return 0; |
| 279 | // Remove the hard-coded boundary for 65535 and let math handle it |
| 280 | |
| 281 | // For 16-bit: use cos32 for efficiency and accuracy |
| 282 | // Map i from [0,65535] to [0,4194304] in cos32 space (zero to quarter wave) |
| 283 | // Formula: 1 - cos(t * π/2) where t goes from 0 to 1 |
| 284 | // sin32/cos32 quarter cycle is 16777216/4 = 4194304 |
| 285 | u32 angle = ((fl::u64)i * 4194304ULL) / 65535ULL; |
| 286 | i32 cos_result = fl::cos32(angle); |
| 287 | |
| 288 | // Convert cos32 output and apply easing formula: 1 - cos(t * π/2) |
| 289 | // cos32 output range is [-2147418112, 2147418112] |
| 290 | // At t=0: cos(0) = 2147418112, result should be 0 |
| 291 | // At t=1: cos(π/2) = 0, result should be 65535 |
| 292 | |
| 293 | const fl::i64 MAX_COS32 = 2147418112LL; |
| 294 | |
| 295 | // Calculate: (MAX_COS32 - cos_result) and scale to [0, 65535] |
| 296 | fl::i64 adjusted = MAX_COS32 - (fl::i64)cos_result; |
| 297 | |
| 298 | // Scale from [0, 2147418112] to [0, 65535] |
| 299 | fl::u64 result = (fl::u64)adjusted * 65535ULL + (MAX_COS32 >> 1); // Add half for rounding |
| 300 | u16 final_result = (u16)(result / (fl::u64)MAX_COS32); |
| 301 | |
| 302 | return final_result; |
| 303 | } |
| 304 | |
| 305 | u16 easeOutSine16(u16 i) { |
| 306 | // ease-out sine: sin(t * π/2) |