@@ -694,35 +694,32 @@ uint16_t Axis::getPower(){
694694/* *
695695 * Calculates an exponential torque correction curve and scale for FFBEffect
696696 */
697- int32_t Axis::calculateExpoTorque (int32_t torque){
698- float torquef = (float )torque / (float )0x7fff ; // This down and upscaling may introduce float artifacts. Do this before scaling down.
699- if (torquef < 0 ){
700- return -powf (-torquef,expo) * 0x7fff ;
701- }else {
702- return powf (torquef,expo) * 0x7fff ;
703- }
697+ float Axis::calculateExpoTorque (float torque){
698+ float torqueSign = torque > 0 ? 1 .0f : -1 .0f ;
699+ torque = powf (fabsf (torque), expo) * torqueSign;
700+ return torque;
704701}
705702
706- int64_t Axis::calculateFFBTorque () {
703+ int32_t Axis::calculateFFBTorque (){
707704
708- int64_t torque = this ->ffbEffectTorque ;
705+ // 1. Initial conversion and normalization
706+ // Convert to float and move to [-1.0, 1.0] range immediately.
707+ float torque = (float )this ->ffbEffectTorque * (1 .0f / 32767 .0f );
709708
710- // 1 . Game Clipping detection
711- // If the game sends more than the theoretical maximum (+/- 32767), the signal is clipped at the source .
712- if (abs (torque) >= 0x7fff ){
709+ // 2 . Game Clipping detection
710+ // Performed on normalized value for consistency .
711+ if (fabsf (torque) >= 1 . 0f ){
713712 pulseClipLed (); // Visual alert: game signal is clipping
714713 }
715714
716- // 2 . Apply Expo (Linearization or sensation curve)
717- if (expo != 1 ){
715+ // 3 . Apply Expo (Linearization or sensation curve)
716+ if (expo != 1 . 0f ){
718717 torque = calculateExpoTorque (torque);
719718 }
720719
721- // 3. Game specific gain (effectRatioScaler)
722- // Scale the FFB from game only (allows lowering game effects without lowering endstops)
723- torque = (int64_t )((float )torque * effectRatioScaler);
724-
725- return torque;
720+ // 4. Final scaling and single conversion back to integer
721+ // Apply both the FFB range and the effect ratio in one final step.
722+ return (int32_t )(torque * 32767 .0f * effectRatioScaler);
726723}
727724
728725int32_t Axis::getTorque () { return metric.current .torque ; } // Fix: move from previous to current
@@ -821,8 +818,8 @@ void Axis::applyTorqueSlewRateLimiter(int32_t& torque)
821818{
822819 // Limits the rate of change of the torque (slew rate), to smooths out sudden changes in torque.
823820 // Essential for a natural feel and to prevent "clanking" noises.
824- if (maxTorqueRateMS = = 0 ) {
825- return ; // Limiter is disabled
821+ if (maxTorqueRateMS < = 0 ) {
822+ return ;
826823 }
827824
828825 // This prevents sudden torque jumps, resulting in a smoother feel.
0 commit comments