mirror of
https://github.com/AntonioND/palib.git
synced 2025-06-18 14:45:43 -04:00
289 lines
9.1 KiB
C
289 lines
9.1 KiB
C
#ifndef _PA_Math
|
|
#define _PA_Math
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include "PA9.h"
|
|
|
|
#include "PA_Interrupt.h"
|
|
|
|
|
|
/** @defgroup Math Math functions
|
|
* Adjust angles, get random values...
|
|
* @{
|
|
*/
|
|
|
|
/*! \def PA_Cos(angle)
|
|
\brief
|
|
\~english Returns the Cos value for an angle. The value goes from -256 to 256... Watch out though : the angle is not in 360 degrees, but in 512 !
|
|
\~french Renvoie la valeur Cosinus d'un angle. Cette valeur est comprise entre -256 et 256... Attention : l'angle n'est pas en 360 degr?s, mais en 512 !
|
|
*/
|
|
#define PA_Cos(angle) PA_SIN[((angle) + 128)&511]
|
|
|
|
|
|
/*! \def PA_Sin(angle)
|
|
\brief
|
|
\~english Returns the Sin value for an angle. The value goes from -256 to 256... Watch out though : the angle is not in 360 degrees, but in 256 !
|
|
\~french Renvoie la valeur Sinus d'un angle. Cette valeur est comprise entre -256 et 256... Attention : l'angle n'est pas en 360 degr?s, mais en 256 !
|
|
*/
|
|
#define PA_Sin(angle) PA_SIN[((angle))&511]
|
|
|
|
extern u32 RandomValue; // Seed pour la fonction random
|
|
|
|
/*! \fn static inline u32 PA_Rand()
|
|
\brief
|
|
\~english Gives a random number, taken from Ham... This is taken from Ham, I have no credit.
|
|
\~french Donne un numéro aléatoire... Ceci est pris de Ham, je n'ai aucun mérite.
|
|
*/
|
|
static inline u32 PA_Rand() {
|
|
u32 lo, hi;
|
|
lo = 16807 * (RandomValue & 0xFFFF);
|
|
hi = 16807 * (RandomValue >> 16);
|
|
lo += (hi & 0x7FFF) << 16;
|
|
lo += hi >> 15;
|
|
if (lo > 0x7FFFFFFF)
|
|
lo -= 0x7FFFFFFF;
|
|
RandomValue = lo;
|
|
return(RandomValue);
|
|
}
|
|
|
|
/*! \fn static inline void PA_InitRand()
|
|
\brief
|
|
\~english Auto-seeds the Rand function based on the clock !
|
|
\~french Initialisation automatique du rand, basé sur l'horloge interne...
|
|
*/
|
|
// Les fonctions randoms sont prises de Ham, je n'ai strictement AUCUN mérite ! Désolé ! Je l'ai un peu modifiée, elle doit etre plus rapide
|
|
static inline void PA_InitRand() {
|
|
RandomValue = 1 + PA_RTC.Seconds + PA_RTC.Minutes*60 + PA_RTC.Hour*3600 + PA_RTC.Day*3600*24+PA_RTC.Month*3600*24*30;
|
|
PA_Rand(); PA_Rand(); PA_Rand(); // On fait plusieurs fois de base
|
|
}
|
|
|
|
/*! \fn void PA_SRand(s32 r)
|
|
\brief
|
|
\~english Set the random's seed. This is taken from Ham, I have no credit. I just made it a little shorter/faster (maybe)
|
|
\~french Initialiser le random avec un seed. Ceci est pris de Ham, je n'ai aucun mérite. J'ai juste raccourci/accéléré un peu le tout
|
|
\~\param r
|
|
\~english Seed value
|
|
\~french Seed...
|
|
|
|
*/
|
|
// Les fonctions randoms sont prises de Ham, je n'ai strictement AUCUN m?rite ! D?sol? ! Je l'ai un peu modifi?e, elle doit etre plus rapide
|
|
static inline void PA_SRand(s32 r) {
|
|
if ((r==-2)||(r==0)||(r==2147483647))
|
|
RandomValue = 1;
|
|
else
|
|
RandomValue = r;
|
|
}
|
|
|
|
/*! \fn static inline u32 PA_RandMax(u32 max)
|
|
\brief
|
|
\~english Gives a random number, between 0 and the given number (included)
|
|
\~french Donne un num?ro al?atoire... Entre 0 et le nombre donn? (inclus)
|
|
\~\param max
|
|
\~english Maximum included value
|
|
\~french Valeur maximale incluse
|
|
*/
|
|
static inline u32 PA_RandMax(u32 max){
|
|
return PA_Rand()%(max + 1);
|
|
}
|
|
|
|
/*! \fn static inline u32 PA_RandMinMax(u32 min,u32 max)
|
|
\brief
|
|
\~english Gives a random number, between the 2 given numbers (included)
|
|
\~french Donne un num?ro al?atoire... Entre les 2 nombres donn?s (inclus)
|
|
\~\param min
|
|
\~english Minimum included value
|
|
\~french Valeur minimale incluse
|
|
\~\param max
|
|
\~english Maximum included value
|
|
\~french Valeur maximale incluse
|
|
*/
|
|
static inline u32 PA_RandMinMax(u32 min,u32 max){
|
|
return ((PA_Rand()%((max + 1)-min)) + min);
|
|
}
|
|
|
|
/*! \fn static inline u32 PA_Distance(s32 x1, s32 y1, s32 x2, s32 y2)
|
|
\brief
|
|
\~english Calculate the distance (squared) between 2 points
|
|
\~french Calculer la distance (au carr?) entre 2 points
|
|
\~\param x1
|
|
\~english X coordinate of the fist point
|
|
\~french Coordonn?e X du premier point
|
|
\~\param y1
|
|
\~english Y coordinate of the first point
|
|
\~french Coordonn?e Y du premier point
|
|
\~\param x2
|
|
\~english X coordinate of the second point
|
|
\~french Coordonn?e X du deuxi?me point
|
|
\~\param y2
|
|
\~english Y coordinate of the second point
|
|
\~french Coordonn?e Y du deuxi?me point
|
|
*/
|
|
static inline u64 PA_Distance(s32 x1, s32 y1, s32 x2, s32 y2) {
|
|
s64 h = x1 - x2;
|
|
s64 v = y1 - y2;
|
|
return(h*h + v*v);
|
|
}
|
|
|
|
/*! \fn static inline u32 PA_TrueDistance(s32 x1, s32 y1, s32 x2, s32 y2)
|
|
\brief
|
|
\~english Calculate the real distance between 2 points. A lot slower than PA_Distance
|
|
\~french Calculer la vraie distance entre 2 points. Beaucoup plus lent que PA_Distance
|
|
\~\param x1
|
|
\~english X coordinate of the fist point
|
|
\~french Coordonn?e X du premier point
|
|
\~\param y1
|
|
\~english Y coordinate of the first point
|
|
\~french Coordonn?e Y du premier point
|
|
\~\param x2
|
|
\~english X coordinate of the second point
|
|
\~french Coordonn?e X du deuxi?me point
|
|
\~\param y2
|
|
\~english Y coordinate of the second point
|
|
\~french Coordonn?e Y du deuxi?me point
|
|
*/
|
|
static inline u64 PA_TrueDistance(s32 x1, s32 y1, s32 x2, s32 y2) {
|
|
s64 h = x1 - x2;
|
|
s64 v = y1 - y2;
|
|
return(swiSqrt(h*h + v*v));
|
|
}
|
|
|
|
/*! \fn u16 PA_AdjustAngle(u16 angle, s16 anglerot, s32 startx, s32 starty, s32 targetx, s32 targety)
|
|
\brief
|
|
\~english Adjust an angle, for example to calculate in which direction an object shoudl turn
|
|
\~french Ajuster un angle, par exemple pour calculer la direction ? prendre par un vaisseau
|
|
\~\param angle
|
|
\~english Base angle, from 0 to 511
|
|
\~french Angle de base, de 0 ? 511
|
|
\~\param anglerot
|
|
\~english For how much to turn...
|
|
\~french De combien tourner...
|
|
\~\param startx
|
|
\~english Initial X position
|
|
\~french Coordonn?e X de base
|
|
\~\param starty
|
|
\~english Initial Y position
|
|
\~french Coordonn?e Y de base
|
|
\~\param targetx
|
|
\~english Target X position
|
|
\~french Coordonn?e X de la cible
|
|
\~\param targety
|
|
\~english Target Y position
|
|
\~french Coordonn?e Y de la cible
|
|
*/
|
|
|
|
u16 PA_AdjustAngle(u16 angle, s16 anglerot, s32 startx, s32 starty, s32 targetx, s32 targety);
|
|
|
|
/*! \fn static inline u16 PA_GetAngle(s32 startx, s32 starty, s32 targetx, s32 targety)
|
|
\brief
|
|
\~english Get the angle, from 0 to 511, formed between the horizontal and the line
|
|
\~french R?cup?rer l'angle, de 0 ? 511, par rapport ? l'horizontale...
|
|
\~\param startx
|
|
\~english Initial X position
|
|
\~french Coordonn?e X de base
|
|
\~\param starty
|
|
\~english Initial Y position
|
|
\~french Coordonn?e Y de base
|
|
\~\param targetx
|
|
\~english Target X position
|
|
\~french Coordonn?e X de la cible
|
|
\~\param targety
|
|
\~english Target Y position
|
|
\~french Coordonn?e Y de la cible
|
|
*/
|
|
static inline u16 PA_GetAngle(s32 startx, s32 starty, s32 targetx, s32 targety) {
|
|
u16 angle = 0;
|
|
u16 anglerot = 180;
|
|
|
|
while(anglerot > 5) {
|
|
angle = PA_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
|
|
anglerot = (anglerot - ((3 * anglerot) >> 3)); // On diminue petit ? petit la rotation...
|
|
}
|
|
|
|
// Ajustement encore plus précis...
|
|
anglerot = 4;
|
|
angle = PA_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
|
|
anglerot = 2;
|
|
angle = PA_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
|
|
anglerot = 1;
|
|
angle = PA_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
|
|
|
|
return angle;
|
|
}
|
|
|
|
// fincs additions
|
|
|
|
/// Simple point structure.
|
|
typedef struct{
|
|
/// X value.
|
|
int x;
|
|
/// Y value.
|
|
int y;
|
|
}PA_Point;
|
|
|
|
/*! \fn int PA_mulf32(int a, int b)
|
|
\brief
|
|
\~english Multiplies two .12 fixed point integers
|
|
\~french (TODO)
|
|
\~\param a
|
|
\~english First number
|
|
\~french Premier nombre
|
|
\~\param b
|
|
\~english Second number
|
|
\~french Deuxième nombre
|
|
*/
|
|
int PA_mulf32(int a, int b);
|
|
|
|
/*! \fn int PA_divf32(int a, int b)
|
|
\brief
|
|
\~english Divides two .12 fixed point integers
|
|
\~french (TODO)
|
|
\~\param a
|
|
\~english First number
|
|
\~french Premier nombre
|
|
\~\param b
|
|
\~english Second number
|
|
\~french Deuxième nombre
|
|
*/
|
|
int PA_divf32(int a, int b);
|
|
|
|
/*! \fn int PA_modf32(int a, int b)
|
|
\brief
|
|
\~english Gets the remainder of the division between two .12 fixed point integers (modulo)
|
|
\~french (TODO)
|
|
\~\param a
|
|
\~english First number
|
|
\~french Premier nombre
|
|
\~\param b
|
|
\~english Second number
|
|
\~french Deuxième nombre
|
|
*/
|
|
int PA_modf32(int a, int b);
|
|
|
|
/*! \fn int PA_sqrtf32(int a)
|
|
\brief
|
|
\~english Gets the square root of a .12 fixed point integer
|
|
\~french (TODO)
|
|
\~\param a
|
|
\~english Number
|
|
\~french Nombre
|
|
*/
|
|
int PA_sqrtf32(int a);
|
|
|
|
/** @} */ // end of Math
|
|
|
|
static inline s32 PA_Modulo(s32 var, s32 modulo){
|
|
while(var < 0) var += modulo;
|
|
return (var%modulo);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|