diff --git a/include/DSGM.h b/include/DSGM.h index 3c4af6c..9256c38 100644 --- a/include/DSGM.h +++ b/include/DSGM.h @@ -35,6 +35,7 @@ typedef short DSGM_ShortStructLabel[0]; typedef int DSGM_IntStructLabel[0]; #include "DSGM_3D.h" +#include "DSGM_atan2Lerp.h" #include "DSGM_misc.h" #include "DSGM_texture.h" #include "DSGM_quaternion.h" diff --git a/include/DSGM_atan2Lerp.h b/include/DSGM_atan2Lerp.h new file mode 100644 index 0000000..756e5a6 --- /dev/null +++ b/include/DSGM_atan2Lerp.h @@ -0,0 +1,44 @@ +// +// trig.h : Basic trigonometry routines. +// +//! \file trig.h +//! \author J Vijn +//! \date 20080130 - 20080210 +// + +/* + dsgmLib adaptations: + + - Only atan2Lerp was needed, all other trigonometry functions are + already present in libnds and were removed from this library + + - Upgraded the code from C++ to C +*/ + +#pragma once + +// These things may already be present in other headers. +typedef unsigned int uint; + +#ifndef countof +#define countof(array) ( sizeof(array)/sizeof(array[0]) ) +#endif + +#ifndef ALIGN +#define ALIGN(n) __attribute__((aligned(n))) +#endif + +// -------------------------------------------------------------------- +// CONSTANTS +// -------------------------------------------------------------------- + +#define BRAD_PI_SHIFT 14 +#define BRAD_PI (1<verts) free(f->verts); diff --git a/source/DSGM_atan2Lerp.c b/source/DSGM_atan2Lerp.c new file mode 100644 index 0000000..58e690d --- /dev/null +++ b/source/DSGM_atan2Lerp.c @@ -0,0 +1,112 @@ +// +// trig.cpp : Basic trigonometry routines. +// +//! \file trig.cpp +//! \author J Vijn +//! \date 20080130 - 20080210 +// +/* === NOTES === + Multiple atan2's present. Select the one you want. + Best performance tends to be with atan2Lerp or possibly atan2Tonc. + If your division really sucks, use atan2Cordic. + + This module still needs a header for some system-specific basics + before you can use it. Specifically, ALIGN and QDIV will needs some + extra effort. +*/ + +/* + dsgmLib adaptations: + + - Only atan2Lerp was needed, all other trigonometry functions are + already present in libnds and were removed from this library + + - Upgraded the code from C++ to C +*/ + +#include "DSGM.h" + +// -------------------------------------------------------------------- +// MACROS / INLINES +// -------------------------------------------------------------------- + +// Get the octant a coordinate pair is in. +#define OCTANTIFY(_x, _y, _o) do { \ + int _t; _o= 0; \ + if(_y< 0) { _x= -_x; _y= -_y; _o += 4; } \ + if(_x<= 0) { _t= _x; _x= _y; _y= -_t; _o += 2; } \ + if(_x<=_y) { _t= _y-_x; _x= _x+_y; _y= _t; _o += 1; } \ +} while(0); + +// Special-case division because I need a little more control +// than divf32 offers +static inline int QDIV(int num, int den, const int bits) { + while(REG_DIVCNT & DIV_BUSY); + REG_DIVCNT = DIV_64_32; + + REG_DIV_NUMER = ((int64)num)<= 0 ? 0 : BRAD_PI); + + int phi, fa, fb, h; + uint t; + + OCTANTIFY(x, y, phi); + phi *= BRAD_PI/4; + + t = QDIV(y, x, ATAN_FP); + h = t % ATANLUT_STRIDE; + fa = atanLUT[t/ATANLUT_STRIDE ]; + fb = atanLUT[t/ATANLUT_STRIDE+1]; + + return phi + ((fa + ((fb-fa)*h >> ATANLUT_STRIDE_SHIFT))>>3); +}