GMISC invsqrt() function.
Fix a 64bit processor bug. Add support for processors where the floating point and integer endianness don't match. Add support for processors with a non-standard floating point format. Update gdisp_streaming demo with extra comments to reflect the above changes.
This commit is contained in:
parent
21afd2b8f1
commit
e6f17baf61
@ -35,9 +35,11 @@
|
||||
/* Builtin Fonts */
|
||||
#define GDISP_INCLUDE_FONT_UI2 FALSE
|
||||
|
||||
#define GFX_USE_GMISC TRUE
|
||||
#define GMISC_NEED_FIXEDTRIG FALSE
|
||||
#define GMISC_NEED_FASTTRIG FALSE
|
||||
#define GMISC_NEED_INVSQRT TRUE
|
||||
#define GFX_USE_GMISC TRUE
|
||||
#define GMISC_NEED_FIXEDTRIG FALSE
|
||||
#define GMISC_NEED_FASTTRIG FALSE
|
||||
#define GMISC_NEED_INVSQRT TRUE
|
||||
//#define GDISP_INVSQRT_MIXED_ENDIAN TRUE
|
||||
//#define GDISP_INVSQRT_REAL_SLOW TRUE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
||||
|
@ -31,15 +31,29 @@
|
||||
#include "gfx.h"
|
||||
#include <math.h>
|
||||
|
||||
#define Lightgrey ()
|
||||
#define Midgrey ()
|
||||
#define Darkgrey (HTML2COLOR(0x303030))
|
||||
|
||||
#define BALLCOLOR1 Red
|
||||
#define BALLCOLOR2 Yellow
|
||||
#define WALLCOLOR HTML2COLOR(0x303030)
|
||||
#define BACKCOLOR HTML2COLOR(0xC0C0C0)
|
||||
#define FLOORCOLOR HTML2COLOR(0x606060)
|
||||
/**
|
||||
* NOTE:
|
||||
*
|
||||
* This demo uses floating point operations. Don't expect it to work with any
|
||||
* speed unless your processor has an FPU.
|
||||
*
|
||||
* If you see garbage inside the ball as it is running rather than the red and yellow
|
||||
* checkerboard pattern then the fast invsqrt() function in GMISC does not work on
|
||||
* your processor.
|
||||
*
|
||||
* You can modify the implementation of invsqrt() by firstly defining
|
||||
* #define GDISP_INVSQRT_MIXED_ENDIAN TRUE
|
||||
* in your gfxconf.h file.
|
||||
*
|
||||
* If it still doesn't work then instead define
|
||||
* #define GDISP_INVSQRT_REAL_SLOW TRUE
|
||||
* in your gfxconf.h file. This should always work although it will probably be slow.
|
||||
*/
|
||||
#define BALLCOLOR1 Red
|
||||
#define BALLCOLOR2 Yellow
|
||||
#define WALLCOLOR HTML2COLOR(0x303030)
|
||||
#define BACKCOLOR HTML2COLOR(0xC0C0C0)
|
||||
#define FLOORCOLOR HTML2COLOR(0x606060)
|
||||
#define SHADOWALPHA (255-255*0.2)
|
||||
|
||||
int main(void) {
|
||||
|
@ -181,11 +181,12 @@
|
||||
#define GWIN_CONSOLE_USE_BASESTREAM FALSE
|
||||
#define GWIN_CONSOLE_USE_FLOAT FALSE
|
||||
#define GWIN_NEED_IMAGE_ANIMATION FALSE
|
||||
#define GDISP_INVSQRT_MIXED_ENDIAN FALSE
|
||||
#define GDISP_INVSQRT_REAL_SLOW FALSE
|
||||
*/
|
||||
|
||||
/* Optional Low Level Driver Definitions */
|
||||
/*
|
||||
#define GDISP_USE_CUSTOM_BOARD FALSE
|
||||
#define GDISP_SCREEN_WIDTH 320
|
||||
#define GDISP_SCREEN_HEIGHT 240
|
||||
#define GDISP_USE_FSMC
|
||||
|
@ -44,9 +44,34 @@
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
* @name GMISC Optional Sizing Parameters
|
||||
* @name GMISC Optional Parameters
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Modifies the @p invsqrt() function to assume a different integer to floating point endianness.
|
||||
* @note Normally the floating point format and the integer format have
|
||||
* the same endianness. Unfortunately there are some strange
|
||||
* processors that don't eg. some very early ARM devices.
|
||||
* For those where the endianness doesn't match you can fix it by
|
||||
* defining GDISP_INVSQRT_MIXED_ENDIAN.
|
||||
* @note This still assumes the processor is using an ieee floating point format.
|
||||
*
|
||||
* If you have a software floating point that uses a non-standard
|
||||
* floating point format (or very strange hardware) then define
|
||||
* GDISP_INVSQRT_REAL_SLOW and it will do it the hard way.
|
||||
*/
|
||||
#ifndef GDISP_INVSQRT_MIXED_ENDIAN
|
||||
#define GDISP_INVSQRT_MIXED_ENDIAN FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Modifies the @p invsqrt() function to do things the long slow way.
|
||||
* @note This causes the @p invsqrt() function to work regardless of the
|
||||
* processor floating point format.
|
||||
* @note This makes the @p invsqrt() function very slow.
|
||||
*/
|
||||
#ifndef GDISP_INVSQRT_REAL_SLOW
|
||||
#define GDISP_INVSQRT_REAL_SLOW FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#endif /* _GMISC_OPTIONS_H */
|
||||
|
@ -143,21 +143,47 @@
|
||||
#endif
|
||||
|
||||
#if GMISC_NEED_INVSQRT
|
||||
// Algorithm based on Quake code
|
||||
float invsqrt(float n) {
|
||||
long i;
|
||||
float x2, y;
|
||||
const float threehalfs = 1.5F;
|
||||
// Algorithm based on Quake code.
|
||||
#if GDISP_INVSQRT_REAL_SLOW
|
||||
#include <math.h>
|
||||
float invsqrt(float n) {
|
||||
return 1.0/sqrt(n);
|
||||
}
|
||||
#else
|
||||
float invsqrt(float n) {
|
||||
int32_t i;
|
||||
float x2;
|
||||
|
||||
x2 = n * 0.5F;
|
||||
y = n;
|
||||
i = * ( long * ) &y; // evil floating point bit level hacking
|
||||
i = 0x5f3759df - ( i >> 1 ); // what the?
|
||||
y = * ( float * ) &i;
|
||||
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
|
||||
//y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration for extra precision, this can be removed
|
||||
return y;
|
||||
}
|
||||
x2 = n * 0.5F;
|
||||
|
||||
// Convert into an int32 (no binary format conversion)
|
||||
#if GDISP_INVSQRT_MIXED_ENDIAN
|
||||
((char *)&i)[0] = ((char *)&n)[3];
|
||||
((char *)&i)[1] = ((char *)&n)[2];
|
||||
((char *)&i)[2] = ((char *)&n)[1];
|
||||
((char *)&i)[3] = ((char *)&n)[0];
|
||||
#else
|
||||
i = *(int32_t *)&n;
|
||||
#endif
|
||||
|
||||
// evil floating point bit level hacking
|
||||
i = 0x5F3759DF - (i >> 1);
|
||||
|
||||
// Convert back to a float (no binary format conversion)
|
||||
#if GDISP_INVSQRT_MIXED_ENDIAN
|
||||
((char *)&n)[0] = ((char *)&i)[3];
|
||||
((char *)&n)[1] = ((char *)&i)[2];
|
||||
((char *)&n)[2] = ((char *)&i)[1];
|
||||
((char *)&n)[3] = ((char *)&i)[0];
|
||||
#else
|
||||
n = *(float *)&i;
|
||||
#endif
|
||||
|
||||
n = n * (1.5F - (x2 * n * n)); // 1st iteration
|
||||
//n = n * (1.5F - (x2 * n * n)); // 2nd iteration for extra precision, this can be removed
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* GFX_USE_GMISC */
|
||||
|
Loading…
Reference in New Issue
Block a user