/***************************************************************************************
    GESTIONNAIRE DE SPRITES
    Il s'agit d'un gestionnaire de sprites, qui utilise ce que je peux faire de
    mieux au niveau des sprites (et y'a intérêt!)
    Ce gestionnaire a pour but de positionner automatiquement les sprites sur l'écran,
    gérer intelligemment la mémoire vidéo (enlever les sprites qui ne sont plus
    utilisés, nettoyer les tiles), détecter les collisions de base, etc.
***************************************************************************************/
typedef struct
{
        const unsigned char *tile_sprite;        //Les données (tiles) du sprite
        unsigned short taille_tiles;                //Taille des données en tiles
        unsigned short n_tile;        //Numéro de tile dans l'OAM
} SPRITE_GBA;

extern int objetsUtilises;
#define MAX_SPRITES_GBA 128
extern SPRITE_GBA sprGba[MAX_SPRITES_GBA] EWRAM_DATA; //Sprites hardware.
extern unsigned int nSprGba, n_tile;

//Crée un nouvel objet
#define CreeObjet(obj_number, char_number, xpos, ypos, obj_mode, obj_shape, obj_size, color_mode, pal_number, prio_to_bg, vflip, hflip, mosaic, rotation, rotation_no, dblsize) \
		MonOAM[obj_number].attr0 = (obj_shape << 14) | (color_mode << 13) | (mosaic << 12) | (obj_mode << 10) | \
								   (rotation << 8) | (dblsize << 9) | (ypos); \
        MonOAM[obj_number].attr1 = (obj_size << 14) | (vflip << 13) | (hflip << 12) | (rotation_no << 9) | (xpos); \
        MonOAM[obj_number].attr2 = (pal_number << 12) | (prio_to_bg << 10) | (char_number);

//Place l'objet en question aux positions XY. Cela ne modifie pas les autres attributs du sprites
#define PlaceObjetXY(obj_number, xpos, ypos) \
        MonOAM[obj_number].attr1 &= 0xFE00; \
        MonOAM[obj_number].attr1 |= (xpos); \
        MonOAM[obj_number].attr0 &= 0xFF00; \
        MonOAM[obj_number].attr0 |= (ypos);

//Détruit le sprite (il ne sera plus visible)
#define DetruitObjet(obj_number) \
        MonOAM[obj_number].attr0 = 240; \
        MonOAM[obj_number].attr1 = 160; \
        MonOAM[obj_number].attr2 = 0;

//Change le numéro de tile de l'objet en question.
#define ChangeTileObjet(obj_number, char_number) \
        ( \
{ \
        MonOAM[obj_number].attr2 &= 0xFC00; MonOAM[obj_number].attr2 |= char_number; \
} \
        )

//Change le numéro de tile de l'objet en question.
#define ChangePrioObjet(obj_number, prio) \
        ( \
{ \
        MonOAM[obj_number].attr2 &= 0xF3FF; MonOAM[obj_number].attr2 |= prio << 10; \
} \
        )

void PositionRelativeObjet16x16(int posX, int posY, int x, int y, int *resultatX, int *resultatY);
unsigned int IWRAM_CODE AjSprite(const unsigned char *adr_sprite, unsigned short taille);
unsigned int IWRAM_CODE AjSpriteRapide(const unsigned char *adr_sprite, unsigned short taille);

extern void ExecSprScript(u32 x, u32 y, const u8 *tiles, const SCRIPT_BLOCK *s, u32 palette);
extern void ExecSprScriptEx(
                                PERSO *p,
                                const u8 *tiles,
                                const SCRIPT_BLOCK *s,
                                u32 palette,
                                u16 alpha,
                                u16 prio,
                                u16 mh,
                                u16 mv);
extern void ExecSprScriptEx2(u32 x, u32 y, const u8 *tiles, const SCRIPT_BLOCK *s, u32 palette, u16 alpha, u16 prio);
extern void ExecSprScriptExPlus(
                                u32 x,
                                u32 y,
                                u32 largeur,
                                u32 hauteur,
                                const char *tiles,
                                const SCRIPT_BLOCK *s,
                                u32 palette,
                                u16 alpha,
                                u16 prio,
                                u16 mh,
                                u16 mv);
