184 lines
4.6 KiB
C
184 lines
4.6 KiB
C
/*
|
|
//////////////////////////////////////////////////////
|
|
// SNDREAL.CXX - Librairie SOUNDxd version 2.0 //
|
|
//////////////////////////////////////////////////////
|
|
// Fonctions de gestion des pseudo-reels //
|
|
//////////////////////////////////////////////////////
|
|
*/
|
|
|
|
#include "SND\snddef.h"
|
|
|
|
#include "SNDinc.h"
|
|
#ifdef U64
|
|
#include <ultra.h>
|
|
#else
|
|
#ifdef PSX
|
|
#include <stddef.h>
|
|
#include <libgte.h>
|
|
#else
|
|
#include <math.h>
|
|
#endif
|
|
#endif
|
|
#include "sndvect.h"
|
|
|
|
/*---------------------------------------------------------*/
|
|
/* MulRealRealSnd: multiplication exacte de 2 SndReal*/
|
|
/* Entrees:r1,r2=reels à multiplier*/
|
|
/* Sortie:resultat (r1*r2)*/
|
|
/*--------------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rMulRealRealSnd(SndReal r1,SndReal r2)
|
|
{
|
|
unsigned long r1p,r2p,t1,t2,t3,t4,r3p;
|
|
|
|
r1p=abs(r1);
|
|
r2p=abs(r2);
|
|
|
|
if ((r1p<0x800) && (r2p<0x800) && (r1p>0xFF) && (r2p>0xFF))
|
|
return ((r1>>8)*(r2>>8));
|
|
|
|
if (r1p<0x7F)
|
|
return ((r1 * (r2>>8))>>8);
|
|
|
|
if (r2p<0x7F)
|
|
return ((r2 * (r1>>8))>>8);
|
|
|
|
t1=(r1p & 0xFFFF) * (r2p & 0xFFFF);
|
|
t2=(r1p & 0xFFFF) * (r2p>>16);
|
|
t3=(r1p>>16) * (r2p & 0xFFFF);
|
|
t4=(r1p>>16) * (r2p >>16);
|
|
|
|
r3p=(t1>>16)+t2+t3+(t4<<16);
|
|
|
|
if ((r1<0)^(r2<0))
|
|
return (SndReal)(0-r3p);
|
|
else
|
|
return (SndReal)r3p;
|
|
}
|
|
|
|
/*---------------------------------------------------------*/
|
|
/* MulRealRealQuickSnd: multiplication rapide de 2 SndReal*/
|
|
/* Entrees:r1,r2=reels à multiplier*/
|
|
/* Sortie:resultat (r1*r2)*/
|
|
/* Valide ssi -abs(ri)>0x800; octet de poid faible non valide*/
|
|
/*--------------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rMulRealRealQuickSnd(SndReal r1,SndReal r2)
|
|
{
|
|
return ((r1>>8)*(r2>>8));
|
|
}
|
|
|
|
/*---------------------------------------------------------*/
|
|
/* SqrtRealSnd: racine carre d'un SndReal*/
|
|
/* Entrees:r dont il faut extraire la racine*/
|
|
/* Sortie:racine carre de r*/
|
|
/*--------------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rSqrtRealSnd(SndReal r)
|
|
{
|
|
#ifdef U64
|
|
return M_DoubleToRealSnd(sqrtf(M_RealToDoubleSnd(r)));
|
|
#else
|
|
#ifdef PSX
|
|
return M_DoubleToRealSnd(csqrt(M_RealToDoubleSnd(r)));
|
|
#else
|
|
return M_DoubleToRealSnd(sqrt(M_RealToDoubleSnd(r)));
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------*/
|
|
/* DivRealRealSnd: division d'un SndReal par un autre SndReal*/
|
|
/* avec peut de precision (1/65000 à 1/256)*/
|
|
/* Entrees:r1=dividente*/
|
|
/* r2=diviseur*/
|
|
/* Sortie:resultat de r1/r2*/
|
|
/*--------------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rDivRealRealQuickSnd(SndReal r1,SndReal r2)
|
|
{
|
|
/*il faut retourner 2^16*r1/r2, c.a.d.*/
|
|
/* r1 !0 7f !80 !8000 !800000 */
|
|
/*r2 ! ! ! ! */
|
|
/*------+----------------------------------------*/
|
|
/*0 7f ! r1<<16 ! ? !r2>>16 */
|
|
/*80 ! . . !r1<<8 !.*/
|
|
/*8000 ! . . !r1<<8 !.*/
|
|
/*800000! . . !r1<<8 !.*/
|
|
if (SND_fn_rAbsRealSnd(r1)<0x8000)
|
|
{/*r1 suffisament petit*/
|
|
snd_assert(r2);
|
|
/*r2 null -> division by zero*/
|
|
return ((r1<<16)/r2);
|
|
}
|
|
if (SND_fn_rAbsRealSnd(r1)<0x800000)
|
|
{/*r1 moyen*/
|
|
snd_assert(r2>>8);/* trop grand e=ecart entre r1 et r2*/
|
|
return ((r1<<8)/(r2>>8));
|
|
}
|
|
/*r1 grand*/
|
|
if (SND_fn_rAbsRealSnd(r2)>0x8000)
|
|
{/*r2 grand*/
|
|
snd_assert(r2>>8);
|
|
return ((r1/(r2>>8))<<8);
|
|
}
|
|
/*vaillle que vaille*/
|
|
snd_assert(r2);
|
|
return (r1/r2)<<16;
|
|
}
|
|
|
|
/*---------------------------------------------------------*/
|
|
/* DivRealRealSnd: division d'un SndReal par un autre SndReal*/
|
|
/* avec precision */
|
|
/* Entrees:r1=dividente*/
|
|
/* r2=diviseur*/
|
|
/* Sortie:resultat de r1/r2*/
|
|
/*--------------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rDivRealRealSnd(SndReal r1,SndReal r2)
|
|
{
|
|
#ifdef PSX
|
|
return SND_fn_rDivRealRealQuickSnd(r1,r2);
|
|
#else
|
|
/*il faut retourner 2^16*r1/r2, c.a.d.*/
|
|
return M_DoubleToRealSnd(
|
|
(float)r1
|
|
/(float)r2);
|
|
#endif
|
|
}
|
|
|
|
/*-----------------------------------*/
|
|
/* Valeur absolu*/
|
|
/*-----------------------------------*/
|
|
SndReal SND_CALL SND_fn_rAbsRealSnd(SndReal r)
|
|
{
|
|
return abs(r);
|
|
}
|
|
|
|
/*------------------------------------------------*/
|
|
/* Calcul rapide et approche de sqrt(a^2+b^2+c^2)*/
|
|
/*------------------------------------------------*/
|
|
SndReal SND_CALL SND_fn_rPseudoNormeRealSnd(SndReal r1,SndReal r2,SndReal r3)
|
|
{
|
|
SndVector v;
|
|
|
|
v.x=r1;
|
|
v.y=r2;
|
|
v.z=r3;
|
|
|
|
return SND_fn_rPseudoNormeVectorSnd(&v);
|
|
}
|
|
|
|
void SND_CALL SND_fn_vSndRealTwinToSndReal(SndRealTwin rtwin,SndReal* pr1,SndReal* pr2)
|
|
{
|
|
if (pr1)
|
|
*pr1=(rtwin>>16)<<8;
|
|
|
|
if (pr2)
|
|
*pr2=(rtwin<<16)>>8;
|
|
}
|
|
|
|
SndRealTwin SND_CALL SND_fn_rtSndRealToSndRealTwin(SndReal r1,SndReal r2)
|
|
{
|
|
snd_assert(r1<M_DoubleToRealSnd(127.0));snd_assert(r2<M_DoubleToRealSnd(127.0));
|
|
|
|
return ((r1<<8)&0xFFFF0000) | ((r2>>8)&0xFFFF);
|
|
}
|
|
|