@@ -519,6 +519,7 @@ void swBindTexture(uint32_t id);
519
519
#endif // RLSW_H
520
520
521
521
522
+ #define RLSW_IMPL
522
523
#ifdef RLSW_IMPL
523
524
524
525
#include <stdlib.h>
@@ -760,6 +761,37 @@ static inline float sw_saturate(float x)
760
761
return x ;
761
762
}
762
763
764
+ static inline float sw_fract (float x )
765
+ {
766
+ // Computes the positive fractional part of a float.
767
+ // Equivalent to fabs(x) - floorf(fabs(x)).
768
+ // Uses IEEE 754 bit tricks for efficiency and edge case handling.
769
+
770
+ union { float f ; uint32_t u ; } v ;
771
+ v .f = x ;
772
+
773
+ // Get absolute value bits (clear sign bit)
774
+ uint32_t abs_bits = v .u & 0x7FFFFFFF ;
775
+
776
+ // Case 1: |x| < 1.0f -> integer part is 0, return |x|
777
+ if (abs_bits < 0x3F800000 ) {
778
+ v .u = abs_bits ; // Ensure positive result
779
+ return v .f ;
780
+ }
781
+
782
+ // Case 2: |x| ≥ 2^24 -> float is an exact integer, return 0.0f
783
+ // Also handles Inf and NaN as 0.0f
784
+ if (abs_bits >= 0x4B000000 ) {
785
+ return 0.0f ;
786
+ }
787
+
788
+ // Case 3: 1.0f ≤ |x| < 2^24 -> compute |x| - floor(|x|)
789
+ v .u = abs_bits ;
790
+ float abs_x = v .f ;
791
+
792
+ return abs_x - floorf (abs_x );
793
+ }
794
+
763
795
static inline int sw_clampi (int v , int min , int max )
764
796
{
765
797
if (v < min ) return min ;
@@ -1668,7 +1700,7 @@ static inline void sw_texture_map(int* out, float in, int max, SWwrap mode)
1668
1700
{
1669
1701
switch (mode ) {
1670
1702
case SW_REPEAT :
1671
- * out = (int )((in - floorf ( in ) ) * max + 0.5f );
1703
+ * out = (int )(sw_fract (in ) * max + 0.5f );
1672
1704
break ;
1673
1705
case SW_CLAMP :
1674
1706
* out = (int )(sw_saturate (in ) * (max - 1 ) + 0.5f );
0 commit comments