/*****************************************************************************

GRAOUMF TRACKER 2

Copyright (c) 1996 - 2002 Laurent de Soras

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Contact the author : laurent@ohmforce.com
More information about this license : http://www.gnu.org/licenses/gpl.html

*****************************************************************************/



#if defined (BASE_CURRENT_HEADER)
	#error Inclusion recursive du header BASE.
#endif
#define	BASE_CURRENT_HEADER

#if ! defined (BASE_HEADER_INCLUDED)
#define	BASE_HEADER_INCLUDED



/*\\\ INCLUDES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include "archi.h"



/*\\\ CONSTANTES ET MACROS PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#define	MIN(x,y)					(((x)<=(y)) ? (x) : (y))
#define	MAX(x,y)					(((x)>=(y)) ? (x) : (y))
#define	ABS(x)					(((x)>=0) ? (x) : -(x))
#define	SGN(x)					(((x)>0) ? 1 : (((x)<0) ? -1 : 0 ))
#define	STRUCT_OFFSET(x,y)	((BYTE *)(&(((x *)0)->y)) - (BYTE *)0)

#define	BASE_peek(x)			(* ((BYTE *)(x)))
#define	BASE_poke(x,y)			(* ((BYTE *)(x)) = (y))
#define	BASE_dpeek(x)			(* ((WORD *)(x)))
#define	BASE_dpoke(x,y)		(* ((WORD *)(x)) = (y))
#define	BASE_lpeek(x)			(* ((LWORD *)(x)))
#define	BASE_lpoke(x,y)		(* ((LWORD *)(x)) = (y))

/* Type non signe, x_int, x_frac, y_int, y_frac */
#define	BASE_ADDX(t,x1,x0,y1,y0)	((x1) + (y1) + ((t)(x0) + (t)(y0) < (t)(x0)))
#define	BASE_SUBX(t,x1,x0,y1,y0)	((x1) - (y1) - ((t)(x0) - (t)(y0) > (t)(x0)))

/* Multiplication SLWORD * ULWORD -> SLWORD de poids fort */
#define	BASE_MUL_32S_32U_U32S(a,b)	((SLWORD) (((SQWORD)(a) * (b)) >> 32))
/*
Traduc en asm:
- eax = a (32 bits signe)
- edx = b (32 bits non signe)
			shr		edx, 1
			imul		edx
			sal		edx, 1
- edx = resultat
On perd 1 bit de precision sur le multiplicateur et 1 bit sur le resultat mais
le resultat est beaucoup plus rapide a calculer. Pour ne pas perdre le dernier
bit du resultat, on peut remplacer la derniere instruction par:
			shdl		edx, eax, 1
*/

/* Multiplication SLWORD * SLWORD -> SLWORD de poids moyen (bits 16 a 47) */
#define	BASE_MUL_32S_32S_M32S(a,b)	((SLWORD) (((SQWORD)(a) * (b)) >> 16))

template <class T> void	BASE_swap (T &x, T &y)
{
	T	temp;

	temp = x;
	x = y;
	y = temp;
}



/*\\\ TYPES & STRUCTURES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

typedef	char	ASCIIDBL [24];	/* Contient un double ecrit sur 24 caracteres ("%+#.16E" dans printf) */



/*\\\ PROTOTYPES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

/*--------------------------------------------------------------------------*/
/*      Routines de conversions diverses                                    */
/*--------------------------------------------------------------------------*/

WORD	BASE_intel_word (WORD a);
LWORD	BASE_intel_lword (LWORD a);
WORD	BASE_moto_word (WORD a);
LWORD	BASE_moto_lword (LWORD a);
WORD	BASE_intel_word_to_moto (WORD a);
LWORD	BASE_intel_lword_to_moto (LWORD a);

WORD	BASE_dpeek_moto (const void *adresse);
WORD	BASE_dpeek_intel (const void *adresse);
void	BASE_dpoke_moto (void *adresse, WORD mot);
void	BASE_dpoke_intel (void *adresse, WORD mot);

LWORD	BASE_lpeek_moto (const void *adresse);
LWORD	BASE_lpeek_intel (const void *adresse);
void	BASE_lpoke_moto (void *adresse, LWORD mot_long);
void	BASE_lpoke_intel (void *adresse, LWORD mot_long);

void	BASE_invert_word (WORD *adresse);
void	BASE_invert_lword (LWORD *adresse);

double	BASE_asciidbl_to_double (const ASCIIDBL ascii);
void		BASE_double_to_asciidbl (double nbr, ASCIIDBL ascii);

signed int	BASE_quartet_to_int (signed int quartet);
int	BASE_get_quartet (long number, int pos);
char	BASE_digit_to_char (int d);
void BASE_slword_to_base (SLWORD n, char *text0, int base, int maxlen);
void BASE_ulword_to_base (ULWORD n, char *text0, int base, int maxlen);
void	BASE_pourcent (ULWORD n1, ULWORD n2, char *text0);
void	BASE_truefalse (bool flag, char *chaine_0);
void	BASE_onoff (bool flag, char *chaine_0);
void	BASE_yesno (bool flag, char *chaine_0);

bool	BASE_compare_id4 (const void *id1_ptr, const void *id2_ptr);

signed long	BASE_power (signed long nbr, int pwr);
inline bool	BASE_is_null (double val);
inline bool	BASE_is_infinite (double val);
inline double	BASE_safe_double_inversion (double val);
inline double	BASE_lin_to_db (double val);
inline double	BASE_db_to_lin (double val);

bool	BASE_double_to_unsigned_q (double nbr, int &num, int &denom, int max_num, int max_denom);

long	BASE_get_distance_in_circular_buffer (long length, signed long reference_cursor, signed long test_cursor);

void	BASE_date_to_absolute_day (long &abs_day, int day, int month, int year);
void  BASE_absolute_day_to_date (long abs_day, int &day, int &month, int &year);

int	BASE_get_fader_pos (double val, double inf_val, double sup_val, int length, bool log_flag = false);
double	BASE_get_fader_val (signed int pos, double inf_val, double sup_val, int length, bool log_flag = false);



/*--------------------------------------------------------------------------*/
/*      Manipulations de chaines                                            */
/*--------------------------------------------------------------------------*/

void	BASE_double_to_fix (char *string_0, double nbr, int pre, int post);
void	BASE_double_to_float (char *string_0, double nbr, int len);
void	BASE_double_to_simple (char *string_0, double nbr);

void	BASE_fill_string (char *s, char c, size_t n, size_t sizemax);
void	BASE_copy_string (const char *ss, char *sd, size_t n, size_t destlen);
void	BASE_invert_string (char *text0);
void	BASE_trim_string (char *text0);
void	BASE_complete_string (char *string_0, size_t new_len);
signed int	BASE_compare_string (const char *s1_0, const char *s2_0);
signed long	BASE_search_in_string_nocase (const char *s1_0, const char *s2_0);
signed int	BASE_parse_command_line (char *text_0, char *argv [], int max_argc, const char *delimiter_0);
bool	BASE_is_delimiter (char	c, const char *delimiter_0);



/*\\\ VARIABLES EXTERNES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ FIN DU FICHIER \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#endif

#undef BASE_CURRENT_HEADER
