/* Génère les quatre alignements image/masque possibles du mode X, stocke les alignements de l'image dans la mémoire vidéo, alloue de la mémoire et génère les alignements de masque, remplit une structure AlignedMaskedImage. L'image et le masque doivent être sous forme octet par pixel et de largeur ImageWidth. Le masque correspond de manière isomorphe(un à un)à l'image, avec chaque octet 0 dans le masque masquant le pixel correspondant à l'image (il n'est pas affiché), et dont chaque octet non-0 permettant au pixel correspondant à l'image d'être affiché. Retourne à 0 en cas d'échec, ou le nombre d'adresses de la mémoire vidéo (jeu de 4 pixels)utilisées en cas de succès.La mémoire allouée n'est pas libérée en cas d'échec. Testé avec Borland C++ 4.02 en modèle small par Jim Mischel 12/16/94. */ #include #include #include "maskim.h" extern void CopySystemToScreenX(int, int, int, int, int, int, char *, unsigned int, int, int); unsigned int CreateAlignedMaskedImage(MaskedImage * ImageToSet, unsigned int DispMemStart, char * Image, int ImageWidth, int ImageHeight, char * Mask) { int Align, ScanLine, BitNum, Size, TempImageWidth; unsigned char MaskTemp; unsigned int DispMemOffset = DispMemStart; AlignedMaskedImage *WorkingAMImage; char *NewMaskPtr, *OldMaskPtr; /* Génère les quatre alignements l'un après l'autre */ for (Align = 0; Align < 4; Align++) { /* Alloue de l'espace à la structure AlignedMaskedImage pour cet alignement */ if ((WorkingAMImage = ImageToSet->Alignments[Align] = malloc(sizeof(AlignedMaskedImage))) == NULL) return 0; WorkingAMImage->ImageWidth = (ImageWidth + Align + 3) / 4; /* largeur en jeu de 4 pixels */ WorkingAMImage->ImagePtr = DispMemOffset; /* destination de l'image */ /* Télécharge cet alignement de l'image */ CopySystemToScreenX(0, 0, ImageWidth, ImageHeight, Align, 0, Image, DispMemOffset, ImageWidth, WorkingAMImage->ImageWidth * 4); /* Calcule le nombre d'octets nécessaires pour stocker le masque sous un format 4 bits (utilisable directement par le Map Mask), puis alloue cet espace */ Size = WorkingAMImage->ImageWidth * ImageHeight; if ((WorkingAMImage->MaskPtr = malloc(Size)) == NULL) return 0; /* Génère cet alignement 4 bits (utilisable directement par le Map Mask) du masque, une ligne d'affichage à la fois */ OldMaskPtr = Mask; NewMaskPtr = WorkingAMImage->MaskPtr; for (ScanLine = 0; ScanLine < ImageHeight; ScanLine++) { BitNum = Align; MaskTemp = 0; TempImageWidth = ImageWidth; do { /* Paramètre le masque de bits pour le prochain pixel conformément à cet alignement */ MaskTemp |= (*OldMaskPtr++ != 0) << BitNum; if (++BitNum > 3) { *NewMaskPtr++ = MaskTemp; MaskTemp = BitNum = 0; } } while (--TempImageWidth); /* Paramètre n'importe quel masque de bits sur cette ligne d'affichage */ if (BitNum != 0) *NewMaskPtr++ = MaskTemp; } DispMemOffset += Size; /* délimite l'espace que nous venons d'utiliser */ } return DispMemOffset - DispMemStart; }