1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
#define SPR_MAX_NB 2048
struct SSprite pSpr[SPR_MAX_NB];
u32 gnSprNbSprites; // Nb de sprites capturés.
// Pour tri des sprites à chaque frame.
struct SSprStockage
{
u32 nSprNo;
s32 nPosX, nPosY;
u32 nPrio;
};
#define SPR_STO_MAX 512
struct SSprStockage gpSprSto[SPR_STO_MAX];
struct SSprStockage *gpSprSort[SPR_STO_MAX]; // Pour tri.
u32 gnSprSto; // Nb de sprites stockés pour affichage.
// Initialisation du moteur.
void SprInitEngine(void)
{
gnSprNbSprites = 0; // Nb de sprites capturés.
gnSprSto = 0; // Nb de sprites stockés pour affichage.
}
// Nettoyage.
void SprRelease(void)
{
u32 i;
for (i = 0; i < gnSprNbSprites; i++)
{
free(pSpr[i].pGfx);
}
}
// Récupération des sprites d'une planche.
// In: pSprPal == NULL, on ne sauvegarde pas la palette.
// pSprPal != NULL, on sauvegarde la palette de nPalIdx à 256.
void SprLoadBMP(char *pFilename, SDL_Color *pSprPal, u32 nPalIdx)
{
SDL_Surface *pPlanche;
u32 nNbSprPlanche = 0;
// Lecture du BMP.
pPlanche = SDL_LoadBMP(pFilename);
if (pPlanche == NULL) {
fprintf(stderr, "Couldn't load picture: %s\n", SDL_GetError());
exit(1);
}
// Sauvegarde la palette ?
if (pSprPal != NULL)
{
SDL_Color *pSrcPal = pPlanche->format->palette->colors;
u32 i;
for (i = nPalIdx; i < 256; i++)
{
pSprPal[i - nPalIdx] = pSrcPal[i];
}
}
// On parcourt la planche pour en extraire les sprites.
u32 ix, iy;
u8 *pPix = (u8 *)pPlanche->pixels;
#ifdef DISPLAY_INFO
printf("w = %d / h = %d\n", pPlanche->w, pPlanche->h);
#endif
for (iy = 0; iy < (u32)pPlanche->h; iy++)
{
for (ix = 0; ix < (u32)pPlanche->w; ix++)
{
// On tombe sur un sprite ?
if (*(pPix + (iy * pPlanche->pitch) + ix) == 0)
{
// On a encore de la place ?
if (gnSprNbSprites >= SPR_MAX_NB)
{
printf("Spr: No more sprites slots available.\n");
SprRelease();
exit(1);
// Fainéantise, on peut faire un système de realloc tous les x sprites.
}
#ifdef DISPLAY_INFO
printf("sprite at (%d, %d)\n", (int)ix, (int)iy);
#endif
u32 LgExt, HtExt;
u32 PtRefX, PtRefY; // Pts de ref.
u32 ii, ij, ik;
// Recherche des largeurs extérieures (cadre de 1 pixel). + Pts de ref.
PtRefX = 0;
LgExt = 1;
ii = ix + 1;
while(*(pPix + (iy * pPlanche->pitch) + ii) == 0 || *(pPix + (iy * pPlanche->pitch) + ii + 1) == 0)
{
if (*(pPix + (iy * pPlanche->pitch) + ii) != 0) PtRefX = LgExt - 1;
ii++;
LgExt++;
}
PtRefY = 0;
HtExt = 1;
ii = iy + 1;
while(*(pPix + (ii * pPlanche->pitch) + ix) == 0 || *(pPix + ((ii + 1) * pPlanche->pitch) + ix) == 0)
{
if (*(pPix + (ii * pPlanche->pitch) + ix) != 0) PtRefY = HtExt - 1;
ii++;
HtExt++;
}
#ifdef DISPLAY_INFO
printf("lg ext = %d / ht ext = %d / ref (%d, %d)\n", (int)LgExt, (int)HtExt, (int)PtRefX, (int)PtRefY);
#endif
// Stockage des valeurs.
pSpr[gnSprNbSprites].nPtRefX = PtRefX;
pSpr[gnSprNbSprites].nPtRefY = PtRefY;
pSpr[gnSprNbSprites].nLg = LgExt - 2;
pSpr[gnSprNbSprites].nHt = HtExt - 2;
// Avec un seul malloc (taille gfx + taille masque).
pSpr[gnSprNbSprites].pGfx = (u8 *)malloc(pSpr[gnSprNbSprites].nLg * pSpr[gnSprNbSprites].nHt * 2);
if (pSpr[gnSprNbSprites].pGfx == NULL)
{
printf("Spr: malloc failed.\n");
SprRelease();
exit(1);
}
pSpr[gnSprNbSprites].pMask = pSpr[gnSprNbSprites].pGfx + (pSpr[gnSprNbSprites].nLg * pSpr[gnSprNbSprites].nHt);
// Récupération du sprite + génération du masque.
ik = 0;
for (ij = 0; ij < HtExt - 2; ij++)
{
for (ii = 0; ii < LgExt - 2; ii++)
{
pSpr[gnSprNbSprites].pGfx[ik] = *(pPix + ((iy + ij + 1) * pPlanche->pitch) + (ix + ii + 1));
pSpr[gnSprNbSprites].pMask[ik] = (pSpr[gnSprNbSprites].pGfx[ik] ? 0 : 255);
ik++;
}
}
// Effacement du sprite dans la planche originale.
for (ij = 0; ij < HtExt; ij++)
{
for (ii = 0; ii < LgExt; ii++)
{
*(pPix + ((iy + ij) * pPlanche->pitch) + (ix + ii)) = 255;
}
}
// Terminé.
nNbSprPlanche++;
gnSprNbSprites++;
}
}
} |
Partager