Skip to content

Commit

Permalink
Added SDL_modf() and SDL_modff()
Browse files Browse the repository at this point in the history
This function is useful for accumulating relative mouse motion if you want to only handle whole pixel movement.
e.g.
static float dx_frac, dy_frac;
float dx, dy;

/* Accumulate new motion with previous sub-pixel motion */
dx = event.motion.xrel + dx_frac;
dy = event.motion.yrel + dy_frac;

/* Split the integral and fractional motion, dx and dy will contain whole pixel deltas */
dx_frac = SDL_modff(dx, &dx);
dy_frac = SDL_modff(dy, &dy);
if (dx != 0.0f || dy != 0.0f) {
    ...
}
  • Loading branch information
slouken committed Dec 30, 2022
1 parent ead4f12 commit 7f23d71
Show file tree
Hide file tree
Showing 20 changed files with 149 additions and 7 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -962,8 +962,8 @@ if(SDL_LIBC)
_stricmp _strnicmp sscanf
acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf
copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf
log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf
sin sinf sqrt sqrtf tan tanf trunc truncf)
log logf log10 log10f lround lroundf modf modff pow powf round roundf
scalbn scalbnf sin sinf sqrt sqrtf tan tanf trunc truncf)
string(TOUPPER ${_FN} _UPPER)
set(HAVE_${_UPPER} 1)
endforeach()
Expand Down
1 change: 1 addition & 0 deletions VisualC-GDK/SDL/SDL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@
<ClCompile Include="..\..\src\libm\s_cos.c" />
<ClCompile Include="..\..\src\libm\s_fabs.c" />
<ClCompile Include="..\..\src\libm\s_floor.c" />
<ClCompile Include="..\..\src\libm\s_modf.c" />
<ClCompile Include="..\..\src\libm\s_scalbn.c" />
<ClCompile Include="..\..\src\libm\s_sin.c" />
<ClCompile Include="..\..\src\libm\s_tan.c" />
Expand Down
3 changes: 3 additions & 0 deletions VisualC-GDK/SDL/SDL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,9 @@
<ClCompile Include="..\..\src\libm\s_floor.c">
<Filter>libm</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\s_modf.c">
<Filter>libm</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\s_scalbn.c">
<Filter>libm</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions VisualC/SDL/SDL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@
<ClCompile Include="..\..\src\libm\s_cos.c" />
<ClCompile Include="..\..\src\libm\s_fabs.c" />
<ClCompile Include="..\..\src\libm\s_floor.c" />
<ClCompile Include="..\..\src\libm\s_modf.c" />
<ClCompile Include="..\..\src\libm\s_scalbn.c" />
<ClCompile Include="..\..\src\libm\s_sin.c" />
<ClCompile Include="..\..\src\libm\s_tan.c" />
Expand Down
3 changes: 3 additions & 0 deletions VisualC/SDL/SDL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,9 @@
<ClCompile Include="..\..\src\libm\s_floor.c">
<Filter>libm</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\s_modf.c">
<Filter>libm</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\s_scalbn.c">
<Filter>libm</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions WhatsNew.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ General:
* Added SDL_GetTicksNS() to return the number of nanoseconds since the SDL library initialized
* Added SDL_DelayNS() to specify a delay in nanoseconds, to the highest precision the system will support
* The timestamp member of the SDL_Event structure is now in nanoseconds, filled in with the time the event was generated, or the time it was queued if that's not available
* Added SDL_modf() and SDL_modff() to separate the whole and fractional portions of a floating point number
2 changes: 2 additions & 0 deletions include/SDL3/SDL_stdinc.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ extern DECLSPEC double SDLCALL SDL_log(double x);
extern DECLSPEC float SDLCALL SDL_logf(float x);
extern DECLSPEC double SDLCALL SDL_log10(double x);
extern DECLSPEC float SDLCALL SDL_log10f(float x);
extern DECLSPEC double SDLCALL SDL_modf(double x, double *y);
extern DECLSPEC float SDLCALL SDL_modff(float x, float *y);
extern DECLSPEC double SDLCALL SDL_pow(double x, double y);
extern DECLSPEC float SDLCALL SDL_powf(float x, float y);
extern DECLSPEC double SDLCALL SDL_round(double x);
Expand Down
2 changes: 2 additions & 0 deletions include/build_config/SDL_build_config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@
#cmakedefine HAVE_LOG10F 1
#cmakedefine HAVE_LROUND 1
#cmakedefine HAVE_LROUNDF 1
#cmakedefine HAVE_MODF 1
#cmakedefine HAVE_MODFF 1
#cmakedefine HAVE_POW 1
#cmakedefine HAVE_POWF 1
#cmakedefine HAVE_ROUND 1
Expand Down
1 change: 1 addition & 0 deletions include/build_config/SDL_build_config_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
#define HAVE_LOG10F 1
#define HAVE_LROUND 1
#define HAVE_LROUNDF 1
#define HAVE_MODF 1
#define HAVE_POW 1
#define HAVE_POWF 1
#define HAVE_ROUND 1
Expand Down
1 change: 1 addition & 0 deletions include/build_config/SDL_build_config_ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
#define HAVE_LOG10F 1
#define HAVE_LROUND 1
#define HAVE_LROUNDF 1
#define HAVE_MODF 1
#define HAVE_POW 1
#define HAVE_POWF 1
#define HAVE_ROUND 1
Expand Down
1 change: 1 addition & 0 deletions include/build_config/SDL_build_config_macos.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@
#define HAVE_LOG10F 1
#define HAVE_LROUND 1
#define HAVE_LROUNDF 1
#define HAVE_MODF 1
#define HAVE_POW 1
#define HAVE_POWF 1
#define HAVE_ROUND 1
Expand Down
1 change: 1 addition & 0 deletions include/build_config/SDL_build_config_winrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
#define HAVE_LOG10F 1
#define HAVE_LROUND 1
#define HAVE_LROUNDF 1
#define HAVE_MODF 1
#define HAVE_POW 1
#define HAVE_POWF 1
#define HAVE_ROUND 1
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,8 @@ SDL3_0.0.0 {
SDL_wcsncasecmp;
SDL_wcsncmp;
SDL_wcsstr;
SDL_modf;
SDL_modff;
# extra symbols go here (don't modify this line)
local: *;
};
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -887,3 +887,5 @@
#define SDL_wcsstr SDL_wcsstr_REAL

/* New API symbols are added at the end */
#define SDL_modf SDL_modf_REAL
#define SDL_modff SDL_modff_REAL
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,3 +932,5 @@ SDL_DYNAPI_PROC(int,SDL_wcsncmp,(const wchar_t *a, const wchar_t *b, size_t c),(
SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)

/* New API symbols are added at the end */
SDL_DYNAPI_PROC(double,SDL_modf,(double a, double *b),(a,b),return)
SDL_DYNAPI_PROC(float,SDL_modff,(float a, float *b),(a,b),return)
11 changes: 6 additions & 5 deletions src/libm/math_libm.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@
/* Math routines from uClibc: http://www.uclibc.org */

double SDL_uclibc_atan(double x);
double SDL_uclibc_atan2(double y, double x);
double SDL_uclibc_copysign(double x, double y);
double SDL_uclibc_cos(double x);
double SDL_uclibc_atan2(double y, double x);
double SDL_uclibc_copysign(double x, double y);
double SDL_uclibc_cos(double x);
double SDL_uclibc_exp(double x);
double SDL_uclibc_fabs(double x);
double SDL_uclibc_fabs(double x);
double SDL_uclibc_floor(double x);
double SDL_uclibc_fmod(double x, double y);
double SDL_uclibc_log(double x);
double SDL_uclibc_log10(double x);
double SDL_uclibc_pow(double x, double y);
double SDL_uclibc_modf(double x, double *y);
double SDL_uclibc_pow(double x, double y);
double SDL_uclibc_scalbn(double x, int n);
double SDL_uclibc_sin(double x);
double SDL_uclibc_sqrt(double x);
Expand Down
1 change: 1 addition & 0 deletions src/libm/math_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ typedef unsigned int u_int32_t;
#define __ieee754_fmod SDL_uclibc_fmod
#define __ieee754_log SDL_uclibc_log
#define __ieee754_log10 SDL_uclibc_log10
#define modf SDL_uclibc_modf
#define __ieee754_pow SDL_uclibc_pow
#define scalbln SDL_uclibc_scalbln
#define scalbn SDL_uclibc_scalbn
Expand Down
68 changes: 68 additions & 0 deletions src/libm/s_modf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "SDL_internal.h"
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

/*
* modf(double x, double *iptr)
* return fraction part of x, and return x's integral part in *iptr.
* Method:
* Bit twiddling.
*
* Exception:
* No exception.
*/

#include "math_libm.h"
#include "math_private.h"

static const double one = 1.0;

double modf(double x, double *iptr)
{
int32_t i0,i1,_j0;
u_int32_t i;
EXTRACT_WORDS(i0,i1,x);
_j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
if(_j0<20) { /* integer part in high x */
if(_j0<0) { /* |x|<1 */
INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
return x;
} else {
i = (0x000fffff)>>_j0;
if(((i0&i)|i1)==0) { /* x is integral */
*iptr = x;
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0&(~i),0);
return x - *iptr;
}
}
} else if (_j0>51) { /* no fraction part */
*iptr = x*one;
/* We must handle NaNs separately. */
if (_j0 == 0x400 && ((i0 & 0xfffff) | i1))
return x*one;
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else { /* fraction part in low x */
i = ((u_int32_t)(0xffffffff))>>(_j0-20);
if((i1&i)==0) { /* x is integral */
*iptr = x;
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0,i1&(~i));
return x - *iptr;
}
}
}
libm_hidden_def(modf)
22 changes: 22 additions & 0 deletions src/stdlib/SDL_stdlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,28 @@ float SDL_log10f(float x)
#endif
}

double
SDL_modf(double x, double *y)
{
#if defined(HAVE_MODF)
return modf(x, y);
#else
return SDL_uclibc_modf(x, y);
#endif
}

float SDL_modff(float x, float *y)
{
#if defined(HAVE_MODFF)
return modff(x, y);
#else
double double_result, double_y;
double_result = SDL_modf((double)x, &double_y);
*y = (float)double_y;
return (float)double_result;
#endif
}

double
SDL_pow(double x, double y)
{
Expand Down
27 changes: 27 additions & 0 deletions test/testautomation_math.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,24 @@ log10_regularCases(void *args)
return helper_dtod_inexact("Log10", SDL_log10, regular_cases, SDL_arraysize(regular_cases));
}

/* SDL_modf tests functions */

static int
modf_baseCases(void *args)
{
double fractional, integral;

fractional = SDL_modf(1.25, &integral);
SDLTest_AssertCheck(integral == 1.0,
"modf(%f), expected integral %f, got %f",
1.25, 1.0, integral);
SDLTest_AssertCheck(fractional == 0.25,
"modf(%f), expected fractional %f, got %f",
1.25, 0.25, fractional);

return TEST_COMPLETED;
}

/* SDL_pow tests functions */

/* Tests with positive and negative infinities as exponents */
Expand Down Expand Up @@ -3004,6 +3022,13 @@ static const SDLTest_TestCaseReference log10TestRegular = {
"Checks a set of regular values", TEST_ENABLED
};

/* SDL_modf test cases */

static const SDLTest_TestCaseReference modfTestBase = {
(SDLTest_TestCaseFp)modf_baseCases, "modf_baseCases",
"Checks the base cases", TEST_ENABLED
};

/* SDL_pow test cases */

static const SDLTest_TestCaseReference powTestExpInf1 = {
Expand Down Expand Up @@ -3315,6 +3340,8 @@ static const SDLTest_TestCaseReference *mathTests[] = {
&log10TestLimit, &log10TestNan,
&log10TestBase, &log10TestRegular,

&modfTestBase,

&powTestExpInf1, &powTestExpInf2, &powTestExpInf3,
&powTestBaseInf1, &powTestBaseInf2,
&powTestNan1, &powTestNan2, &powTestNan3, &powTestNan4,
Expand Down

0 comments on commit 7f23d71

Please sign in to comment.