//Définitions
typedef unsigned char *TABLEAU;

typedef struct
{        //Structure d'un sprite
	int type;                        //Type (identifieur) du sprite
	union
	{
		struct
		{
			int virgule_x;
			int x;
		};
		s64 valeur_x;
	};
	union
	{
		struct
		{
			int virgule_y;
			int y;
		};
		s64 valeur_y;
	};
	int dir;                        //Direction du sprite
	int cpt;                        //Compteur

	//        int etat;                                           //Etat spécial
	void (*fctEtat) ();
	int vx;                                //Vitesse du sprite
	int vy;                                //Sa gravité
	int lastX, lastY;        //Pour la gestion de la caméra
	int saut;                        //Saut effectué
	int hauteur;                //Sa hauteur
	int largeur;                //Sa largeur
	int angle, vangle;        //Angle et angle affiché (vangle)
	int A;
	int vitesseY;
	unsigned char croche, enboule, colBas;        //, colDroite, colGauche;
	unsigned char colHaut, colDroite, colGauche, pousseMurGauche, pousseMurDroite, col2D, colBasObj;
	signed char colSol;
	unsigned short virgule;
	short no_sprite;
	unsigned char premAppui, decole, crochePF;
	unsigned short clignote, invincible, tempsEau;
	u32 score;
	u16 bagues;
	u8 interdit_saut, sous_leau;
	u32 controle;
	u8 enbouleobligatoire;
	u8 prio;

	//        unsigned char enboulesauv;
	u16 pas_angle;        //0x1000/0x0000
} SONIC;

typedef struct
{        //Structure d'un perso
	unsigned short type;                //Type (identifieur) du sprite
	unsigned short x;                        //Position x (absolue)
	unsigned short y;                        //Position y (absolue)
	short virguleX, virguleY;        //Virgule fixe
	unsigned short cpt;                        //Compteur
	unsigned short etat;                //Etat spécial
	unsigned short depX, depY;        //Positions de départ
	short vx;                //Vitesse du sprite
	short vy;                //Sa gravité
	short angle;        //Son angle. Utilisation générale.
	unsigned short hauteur;                        //Sa hauteur
	unsigned short largeur;                        //Sa largeur
	unsigned short (*fHandler) ();        //Handler du personnage en question
	signed char dir;        //Direction
	unsigned short instructions;        //Instructions pour le handler standard. Cela peut lui demander par exemple de signaler s'il y a une collision avec le personnage ou le décor, etc. ou de désactiver ces fonctionnalités dans le cas d'objets statiques par exemple, car cela ne sert à rien à part gaspiller du CPU... Le plus utile est notamment si on a besoin de placer le personnage sur le décor en standard, (c'est très compliqué à faire à chaque fois) ce qui est impossible si le personnage se trouve en dehors de l'écran -> dans ce cas-là, on quitte immédiatement le handler, sans calculs inutiles.
	unsigned short savX, savY;
	unsigned char mort, scroched;
	u16 noObjet;
	u32 donnees[16];
} PERSO;

typedef struct
{
	u16 tile;                //Tile concernée par l'animation
	u16 animbase;        //Base des nouvelles tiles à copier
	u16 timing;                //Timing (lenteur) entre deux animations
	u16 etapes;                //Nombre d'étapes par an
} ANIMATION;

typedef struct
{        //Infos sur l'écran
	TABLEAU Tampon; //"Backbuffer" de l'écran
	int scrlX;                //Scrolling x (toujours modulo 8)
	int scrlY;                //Scrolling y (toujours modulo 8)
} ECRAN;

//A utiliser sur le champ "donnees" des persos. Ces structures peuvent faire jusqu'à 32 octets
typedef struct
{
	//Taille: 16 octets
	u32 param1, param2;
	s16 param3, param4;
	u16 param5, param6;
} DONNEES_STD;

enum etats { ETAT_NORMAL = 0, ETAT_TOUCHE, ETAT_BUMPER, ETAT_MORT};

//Constantes
#define LIMITE_PERSOS        (512 + 64)

enum instructions
{
	INSTR_COLLISION_DECOR        = 0x0001,        //Demande de placer le personnage sur le décor en utilisant les méthodes standard (comme Sonic)
	INSTR_SEULEMENT_ECRAN        = 0x0002,        //Ne fait rien s'il est hors de l'écran
	INSTR_PAS_EFFACER            = 0x0004,        //Ne pas effacer le perso s'il dépasse des limites de l'écran
	INSTR_HORS_MAP               = 0x0008,        //N'est pas dans la map, donc les coordonnées depX et depY ne sont pas associées à un bloc de map
};
enum messages
{
	MSG_COLLISION_SONIC          = 0x0001,        //Message envoyé en réponse à INSTR_COLLISION_SONIC -> le personnage va crever. On lui laisse une dernière chance, peut-être qu'il a plusieurs points de vie ;)
	MSG_AFFICHER                 = 0x0002,        //Message envoyé s'il faut afficher le personnage
};

enum controles
{
	CNT_TOUCHES                  = 0x00000001,
	CNT_COLLISIONS               = 0x00000002,
	CNT_SCROLLING                = 0x00000004,
	CNT_PHYSIQUE                 = 0x00000008,
	CNT_TOUS                     = 0xffffffff
};

//Variables
extern u32 posX, posY;
extern PERSO persos[LIMITE_PERSOS + 2] EWRAM_DATA;
extern int skip, idfct;
extern void *hnest;

//#define SKIP(x)     (x<<skip)

//#define SKIP_ON     (skip)
#define SKIP(x)                          (x)
#define SKIP_ON                          0

#define LitControle(s, cnt)              ((s)->controle & (cnt))
#define ActiveControle(s, cnt)           ((s)->controle |= (cnt))
#define DesactiveControle(s, cnt)        ((s)->controle &= ~(cnt))

enum types_collisions
{
	TC_GAUCHE  = 1,
	TC_DROITE  = 2,
	TC_HAUT    = 4,
	TC_BAS     = 8,
	TC_TOUS    = 15,
	TC_MOUV    = 32,
	TC_ANORMAL = 64
};

#define PARAM(perso)        ((DONNEES_STD*)(perso)->donnees)
