diff --git a/include/SDL3/SDL_bits.h b/include/SDL3/SDL_bits.h index d4a3aff35..1c76d1570 100644 --- a/include/SDL3/SDL_bits.h +++ b/include/SDL3/SDL_bits.h @@ -40,13 +40,6 @@ extern "C" { * \file SDL_bits.h */ -/** - * Get the index of the most significant bit. Result is undefined when called - * with 0. This operation can also be stated as "count leading zeroes" and - * "log base 2". - * - * \return the index of the most significant bit, or -1 if the value is 0. - */ #if defined(__WATCOMC__) && defined(__386__) extern __inline int _SDL_bsr_watcom(Uint32); #pragma aux _SDL_bsr_watcom = \ @@ -56,8 +49,25 @@ extern __inline int _SDL_bsr_watcom(Uint32); modify exact [eax] nomemory; #endif -SDL_FORCE_INLINE int -SDL_MostSignificantBitIndex32(Uint32 x) +/** + * Get the index of the most significant (set) bit in a 32-bit number. + * + * Result is undefined when called with 0. This operation can also be + * stated as "count leading zeroes" and "log base 2". + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param x the 32-bit value to examine + * \returns the index of the most significant bit, or -1 if the value is 0. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +SDL_FORCE_INLINE int SDL_MostSignificantBitIndex32(Uint32 x) { #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) /* Count Leading Zeroes builtin in GCC. @@ -106,8 +116,26 @@ SDL_MostSignificantBitIndex32(Uint32 x) #endif } -SDL_FORCE_INLINE SDL_bool -SDL_HasExactlyOneBitSet32(Uint32 x) +/** + * Determine if a unsigned 32-bit value has exactly one bit set. + * + * If there are no bits set (`x` is zero), or more than one bit set, this + * returns SDL_FALSE. If any one bit is exclusively set, this returns + * SDL_TRUE. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param x the 32-bit value to examine + * \returns SDL_TRUE if exactly one bit is set in `x`, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +SDL_FORCE_INLINE SDL_bool SDL_HasExactlyOneBitSet32(Uint32 x) { if (x && !(x & (x - 1))) { return SDL_TRUE; diff --git a/include/SDL3/SDL_endian.h b/include/SDL3/SDL_endian.h index fb2c62054..7021132bd 100644 --- a/include/SDL3/SDL_endian.h +++ b/include/SDL3/SDL_endian.h @@ -138,31 +138,26 @@ extern "C" { # define HAS_BROKEN_BSWAP 0 #endif -/** - * Byte swap 16-bit integer. - */ +/* Byte swap 16-bit integer. */ #if HAS_BUILTIN_BSWAP16 #define SDL_Swap16(x) __builtin_bswap16(x) #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ushort) #define SDL_Swap16(x) _byteswap_ushort(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); return x; } #elif defined(__x86_64__) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); return x; } #elif (defined(__powerpc__) || defined(__ppc__)) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { int result; @@ -170,8 +165,7 @@ SDL_Swap16(Uint16 x) return (Uint16)result; } #elif (defined(__m68k__) && !defined(__mcoldfire__)) -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); return x; @@ -183,38 +177,32 @@ extern __inline Uint16 SDL_Swap16(Uint16); parm [ax] \ modify [ax]; #else -SDL_FORCE_INLINE Uint16 -SDL_Swap16(Uint16 x) +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); } #endif -/** - * Byte swap 32-bit integer. - */ +/* Byte swap 32-bit integer. */ #if HAS_BUILTIN_BSWAP32 #define SDL_Swap32(x) __builtin_bswap32(x) #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) #pragma intrinsic(_byteswap_ulong) #define SDL_Swap32(x) _byteswap_ulong(x) #elif defined(__i386__) && !HAS_BROKEN_BSWAP -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { __asm__("bswap %0": "=r"(x):"0"(x)); return x; } #elif defined(__x86_64__) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { __asm__("bswapl %0": "=r"(x):"0"(x)); return x; } #elif (defined(__powerpc__) || defined(__ppc__)) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { Uint32 result; @@ -224,8 +212,7 @@ SDL_Swap32(Uint32 x) return result; } #elif (defined(__m68k__) && !defined(__mcoldfire__)) -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); return x; @@ -237,17 +224,14 @@ extern __inline Uint32 SDL_Swap32(Uint32); parm [eax] \ modify [eax]; #else -SDL_FORCE_INLINE Uint32 -SDL_Swap32(Uint32 x) +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) | (x >> 24))); } #endif -/** - * Byte swap 64-bit integer. - */ +/* Byte swap 64-bit integer. */ #if HAS_BUILTIN_BSWAP64 #define SDL_Swap64(x) __builtin_bswap64(x) #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) @@ -270,8 +254,7 @@ SDL_Swap64(Uint64 x) return v.u; } #elif defined(__x86_64__) -SDL_FORCE_INLINE Uint64 -SDL_Swap64(Uint64 x) +SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { __asm__("bswapq %0": "=r"(x):"0"(x)); return x; @@ -285,8 +268,7 @@ extern __inline Uint64 SDL_Swap64(Uint64); parm [eax edx] \ modify [eax edx]; #else -SDL_FORCE_INLINE Uint64 -SDL_Swap64(Uint64 x) +SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { Uint32 hi, lo; @@ -303,10 +285,25 @@ SDL_Swap64(Uint64 x) /** - * Byte swap floating point number. + * Byte-swap a floating point number. + * + * This will always byte-swap the value, whether it's currently in the native + * byteorder of the system or not. You should use SDL_SwapFloatLE or + * SDL_SwapFloatBE instead, in most cases. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param x the value to byte-swap. + * \returns x, with its bytes in the opposite endian order. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. */ -SDL_FORCE_INLINE float -SDL_SwapFloat(float x) +SDL_FORCE_INLINE float SDL_SwapFloat(float x) { union { float f; @@ -325,137 +322,199 @@ SDL_SwapFloat(float x) #ifdef SDL_WIKI_DOCUMENTATION_SECTION +/** + * Byte-swap an unsigned 16-bit number. + * + * This will always byte-swap the value, whether it's currently in the native + * byteorder of the system or not. You should use SDL_SwapLE16 or + * SDL_SwapBE16 instead, in most cases. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param x the value to byte-swap. + * \returns `x`, with its bytes in the opposite endian order. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { return x_but_byteswapped; } /** - * Swap a 16-bit value from littleendian to native format. + * Byte-swap an unsigned 32-bit number. * - * If this is running on a littleendian system, `X` is returned unchanged. + * This will always byte-swap the value, whether it's currently in the native + * byteorder of the system or not. You should use SDL_SwapLE32 or + * SDL_SwapBE32 instead, in most cases. * - * This macro never references `X` more than once, avoiding side effects. + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to byte-swap. + * \returns `x`, with its bytes in the opposite endian order. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; } + +/** + * Byte-swap an unsigned 64-bit number. + * + * This will always byte-swap the value, whether it's currently in the native + * byteorder of the system or not. You should use SDL_SwapLE64 or + * SDL_SwapBE64 instead, in most cases. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param x the value to byte-swap. + * \returns `x`, with its bytes in the opposite endian order. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. + */ +SDL_FORCE_INLINE Uint32 SDL_Swap64(Uint64 x) { return x_but_byteswapped; } + +/** + * Swap a 16-bit value from littleendian to native byte order. + * + * If this is running on a littleendian system, `x` is returned unchanged. + * + * This macro never references `x` more than once, avoiding side effects. + * + * \param x the value to swap, in littleendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapLE16(X) SwapOnlyIfNecessary(X) +#define SDL_SwapLE16(x) SwapOnlyIfNecessary(x) /** - * Swap a 32-bit value from littleendian to native format. + * Swap a 32-bit value from littleendian to native byte order. * - * If this is running on a littleendian system, `X` is returned unchanged. + * If this is running on a littleendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in littleendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapLE32(X) SwapOnlyIfNecessary(X) +#define SDL_SwapLE32(x) SwapOnlyIfNecessary(x) /** - * Swap a 64-bit value from littleendian to native format. + * Swap a 64-bit value from littleendian to native byte order. * - * If this is running on a littleendian system, `X` is returned unchanged. + * If this is running on a littleendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in littleendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapLE64(X) SwapOnlyIfNecessary(X) +#define SDL_SwapLE64(x) SwapOnlyIfNecessary(x) /** - * Swap a floating point value from littleendian to native format. + * Swap a floating point value from littleendian to native byte order. * - * If this is running on a littleendian system, `X` is returned unchanged. + * If this is running on a littleendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in littleendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapFloatLE(X) SwapOnlyIfNecessary(X) +#define SDL_SwapFloatLE(x) SwapOnlyIfNecessary(x) /** - * Swap a 16-bit value from bigendian to native format. + * Swap a 16-bit value from bigendian to native byte order. * - * If this is running on a bigendian system, `X` is returned unchanged. + * If this is running on a bigendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in bigendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapBE16(X) SwapOnlyIfNecessary(X) +#define SDL_SwapBE16(x) SwapOnlyIfNecessary(x) /** - * Swap a 32-bit value from bigendian to native format. + * Swap a 32-bit value from bigendian to native byte order. * - * If this is running on a bigendian system, `X` is returned unchanged. + * If this is running on a bigendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in bigendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapBE32(X) SwapOnlyIfNecessary(X) +#define SDL_SwapBE32(x) SwapOnlyIfNecessary(x) /** - * Swap a 64-bit value from bigendian to native format. + * Swap a 64-bit value from bigendian to native byte order. * - * If this is running on a bigendian system, `X` is returned unchanged. + * If this is running on a bigendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in bigendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapBE64(X) SwapOnlyIfNecessary(X) +#define SDL_SwapBE64(x) SwapOnlyIfNecessary(x) /** - * Swap a floating point value from bigendian to native format. + * Swap a floating point value from bigendian to native byte order. * - * If this is running on a bigendian system, `X` is returned unchanged. + * If this is running on a bigendian system, `x` is returned unchanged. * - * This macro never references `X` more than once, avoiding side effects. + * This macro never references `x` more than once, avoiding side effects. * - * \param X the value to swap. - * \returns the byte-swapped value. + * \param x the value to swap, in bigendian byte order. + * \returns `x` in native byte order. * * \since This macro is available since SDL 3.0.0. */ -#define SDL_SwapFloatBE(X) SwapOnlyIfNecessary(X) +#define SDL_SwapFloatBE(x) SwapOnlyIfNecessary(x) #elif SDL_BYTEORDER == SDL_LIL_ENDIAN -#define SDL_SwapLE16(X) (X) -#define SDL_SwapLE32(X) (X) -#define SDL_SwapLE64(X) (X) -#define SDL_SwapFloatLE(X) (X) -#define SDL_SwapBE16(X) SDL_Swap16(X) -#define SDL_SwapBE32(X) SDL_Swap32(X) -#define SDL_SwapBE64(X) SDL_Swap64(X) -#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#define SDL_SwapLE16(x) (x) +#define SDL_SwapLE32(x) (x) +#define SDL_SwapLE64(x) (x) +#define SDL_SwapFloatLE(x) (x) +#define SDL_SwapBE16(x) SDL_Swap16(x) +#define SDL_SwapBE32(x) SDL_Swap32(x) +#define SDL_SwapBE64(x) SDL_Swap64(x) +#define SDL_SwapFloatBE(x) SDL_SwapFloat(x) #else -#define SDL_SwapLE16(X) SDL_Swap16(X) -#define SDL_SwapLE32(X) SDL_Swap32(X) -#define SDL_SwapLE64(X) SDL_Swap64(X) -#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) -#define SDL_SwapBE16(X) (X) -#define SDL_SwapBE32(X) (X) -#define SDL_SwapBE64(X) (X) -#define SDL_SwapFloatBE(X) (X) +#define SDL_SwapLE16(x) SDL_Swap16(x) +#define SDL_SwapLE32(x) SDL_Swap32(x) +#define SDL_SwapLE64(x) SDL_Swap64(x) +#define SDL_SwapFloatLE(x) SDL_SwapFloat(x) +#define SDL_SwapBE16(x) (x) +#define SDL_SwapBE32(x) (x) +#define SDL_SwapBE64(x) (x) +#define SDL_SwapFloatBE(x) (x) #endif /* Ends C function definitions when using C++ */ diff --git a/include/SDL3/SDL_rect.h b/include/SDL3/SDL_rect.h index fd9aabfa0..616a02642 100644 --- a/include/SDL3/SDL_rect.h +++ b/include/SDL3/SDL_rect.h @@ -112,16 +112,49 @@ typedef struct SDL_FRect /** - * Returns true if point resides inside a rectangle. + * Determine whether a point resides inside a rectangle. + * + * A point is considered part of a rectangle if both `p` and `r` are + * not NULL, and `p`'s x and y coordinates are >= to the rectangle's + * top left corner, and < the rectangle's x+w and y+h. So a 1x1 rectangle + * considers point (0,0) as "inside" and (0,1) as not. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param p the point to test. + * \param r the rectangle to test. + * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. */ SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) { - return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + return ( p && r && (p->x >= r->x) && (p->x < (r->x + r->w)) && (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; } /** - * Returns true if the rectangle has no area. + * Determine whether a rectangle has no area. + * + * A rectangle is considered "empty" for this function if `r` is NULL, + * or if `r`'s width and/or height are <= 0. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param r the rectangle to test. + * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. */ SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) { @@ -129,7 +162,23 @@ SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) } /** - * Returns true if the two rectangles are equal. + * Determine whether two rectangles are equal. + * + * Rectangles are considered equal if both are not NULL and each of their + * x, y, width and height match. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param a the first rectangle to test. + * \param b the second rectangle to test. + * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. */ SDL_FORCE_INLINE SDL_bool SDL_RectsEqual(const SDL_Rect *a, const SDL_Rect *b) { @@ -146,12 +195,14 @@ SDL_FORCE_INLINE SDL_bool SDL_RectsEqual(const SDL_Rect *a, const SDL_Rect *b) * \param B an SDL_Rect structure representing the second rectangle * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. * + * \threadsafety It is safe to call this function from any thread. + * * \since This function is available since SDL 3.0.0. * * \sa SDL_GetRectIntersection */ extern DECLSPEC SDL_bool SDLCALL SDL_HasRectIntersection(const SDL_Rect * A, - const SDL_Rect * B); + const SDL_Rect * B); /** * Calculate the intersection of two rectangles. @@ -237,16 +288,47 @@ extern DECLSPEC SDL_bool SDLCALL SDL_GetRectAndLineIntersection(const SDL_Rect * /* SDL_FRect versions... */ /** - * Returns true if point resides inside a rectangle. + * Determine whether a point resides inside a floating point rectangle. + * + * A point is considered part of a rectangle if both `p` and `r` are + * not NULL, and `p`'s x and y coordinates are >= to the rectangle's + * top left corner, and < the rectangle's x+w and y+h. So a 1x1 rectangle + * considers point (0,0) as "inside" and (0,1) as not. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param p the point to test. + * \param r the rectangle to test. + * \returns SDL_TRUE if `p` is contained by `r`, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.0.0. */ SDL_FORCE_INLINE SDL_bool SDL_PointInRectFloat(const SDL_FPoint *p, const SDL_FRect *r) { - return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + return ( p && r && (p->x >= r->x) && (p->x < (r->x + r->w)) && (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; } /** - * Returns true if the rectangle has no area. + * Determine whether a floating point rectangle has no area. + * + * A rectangle is considered "empty" for this function if `r` is NULL, + * or if `r`'s width and/or height are <= 0.0f. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param r the rectangle to test. + * \returns SDL_TRUE if the rectangle is "empty", SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. */ @@ -256,9 +338,27 @@ SDL_FORCE_INLINE SDL_bool SDL_RectEmptyFloat(const SDL_FRect *r) } /** - * Returns true if the two rectangles are equal, within some given epsilon. + * Determine whether two floating point rectangles are equal, within some given epsilon. + * + * Rectangles are considered equal if both are not NULL and each of their + * x, y, width and height are within `epsilon` of each other. If you don't + * know what value to use for `epsilon`, you should call the + * SDL_RectsEqualFloat function instead. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param a the first rectangle to test. + * \param b the second rectangle to test. + * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. + * + * \sa SDL_RectsEqualFloat */ SDL_FORCE_INLINE SDL_bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon) { @@ -271,9 +371,28 @@ SDL_FORCE_INLINE SDL_bool SDL_RectsEqualEpsilon(const SDL_FRect *a, const SDL_FR } /** - * Returns true if the two rectangles are equal, using a default epsilon. + * Determine whether two floating point rectangles are equal, within a default epsilon. + * + * Rectangles are considered equal if both are not NULL and each of their + * x, y, width and height are within SDL_FLT_EPSILON of each other. This is + * often a reasonable way to compare two floating point rectangles and + * deal with the slight precision variations in floating point calculations + * that tend to pop up. + * + * Note that this is a forced-inline function in a header, and not a public + * API function available in the SDL library (which is to say, the code is + * embedded in the calling program and the linker and dynamic loader will + * not be able to find this function inside SDL itself). + * + * \param a the first rectangle to test. + * \param b the second rectangle to test. + * \returns SDL_TRUE if the rectangles are equal, SDL_FALSE otherwise. + * + * \threadsafety It is safe to call this function from any thread. * * \since This function is available since SDL 3.0.0. + * + * \sa SDL_RectsEqualEpsilon */ SDL_FORCE_INLINE SDL_bool SDL_RectsEqualFloat(const SDL_FRect *a, const SDL_FRect *b) {