[English]

NEWS
INTRODUCTION
TERMINOLOGIE
LE CODE SOURCE
LES BUGS
TUTORIAUX
DOWNLOADS
L'AUTEUR

  LES BUGS: CAPTURES D'ECRAN SINISTRES
Modification de Code Source par ...pyth

Captures d'écran sinistres ? Oui, sir, il s'agit du présent sujet dans lequel vous constaterez que 32 bits semblent gêner notre jeu vidéo préféré ! Un sujet quelque peu important, surtout si vous avez dans l'esprit l'idée d'exposer votre travail de mods aux autres, chose aussi valable pour les gamers...

1) Les faits

Imaginez juste que vous êtes dans une situation vraiment cool dans le jeu, par exemple: vous avez une capture d'écran de tueur en tant qu'Alien avec un carnage total que vous aimeriez bien immortaliser. Et si vous preniez une capture d'écran pour vos amis, hein ?! Eh bien, maintenant imaginez que vous êtes trop content de la prendre mais attendez... merdouille ! L'image est en noir & blanc ! Arghh !!! La chose apparaît si vous êtes dans un mode vidéo en 32 bits par pixel: tout est foutu en l'air avec des sales lignes et le truc est totalement en noir et blanc ! J'ai rencontré le problème sur un système d'exploitation Windows XP en résolution d'écran de 1024 x 768 X 32...

Voici un exemple plus explicite:
Quelque peu dérangeant, nan ?!!! (Il s'agit du premier niveau du Predator... si si ;) )

2) Correction

Dans cette partie, nous corrigerons 2 choses: le bug de capture d'écran, plus un autre détail dans le code code (voyez les commentaires pour cela). Maintenant, ouvrez juste le fichier Scrshot.cpp et localisez la fonction "Screenshot()". Le listing complet à modifier est en dessous...
void ScreenShot()
{
char Name[40];
strcpy(Name,"AVP");
int length=strlen(Name);
strncpy(&Name[length],"00.bmp",8);
for(int i=0;i<100;i++)
{
Name[length]=i/10+'0';
Name[length+1]=(i%10)+'0';
FILE* tempfp=fopen(Name,"r");
if(!tempfp)break;
else
{
fclose(tempfp);
}
}
if(i==100) return;

FILE * fp = fopen(Name,"wb");
if (!fp)
{
return;
}

BMPHEADER2 h;

// fill out header

h.Header.Type = 'B'+'M'*256;
h.Header.Reserved1 = 0;
h.Header.Reserved2 = 0;
h.Header.Offset = 14+40+0;

/*
** The type of information found in a BMP structure is indicated by
** the Size (Information Headere Size) field with a non-zero value.
*/
h.PmInfo.Size = 0;
h.Pm2Info.Size = 0;

h.WinInfo.Size = 40;
h.WinInfo.Width = ScreenDescriptorBlock.SDB_Width;
h.WinInfo.Height = ScreenDescriptorBlock.SDB_Height;
h.WinInfo.Planes = 1;
h.WinInfo.BitCount = 24;
h.WinInfo.Compression = 0;
h.WinInfo.SizeImage = h.WinInfo.Width*h.WinInfo.Height*3;
h.WinInfo.XPelsPerMeter = h.WinInfo.Width;
h.WinInfo.YPelsPerMeter = h.WinInfo.Height;
h.WinInfo.ClrUsed = 0;
h.WinInfo.ClrImportant = 0;

// La taille de fichier (filesize) doit être la somme de la taille de l'image & de l'entête, donc le 8 est une erreur...
//
h.Header.FileSize = h.WinInfo.SizeImage + h.Header.Offset + 8;
h.Header.FileSize = h.WinInfo.SizeImage + h.Header.Offset;

// write header

PutWord_F PutWord = PutLittleWord;
PutDword_F PutDword = PutLittleDword;

PutWord(h.Header.Type, fp);
PutDword(h.Header.FileSize, fp);
PutWord(h.Header.Reserved1, fp);
PutWord(h.Header.Reserved2, fp);
PutDword(h.Header.Offset, fp);

PutDword(h.WinInfo.Size, fp);

PutDword(h.WinInfo.Width, fp);
PutDword(h.WinInfo.Height, fp);
PutWord(h.WinInfo.Planes, fp);
PutWord(h.WinInfo.BitCount, fp);
PutDword(h.WinInfo.Compression, fp);
PutDword(h.WinInfo.SizeImage, fp);
PutDword(h.WinInfo.XPelsPerMeter, fp);
PutDword(h.WinInfo.YPelsPerMeter, fp);
PutDword(h.WinInfo.ClrUsed, fp);
PutDword(h.WinInfo.ClrImportant, fp);


int red_shift,red_scale,green_shift,green_scale,blue_shift,blue_scale;
// Nous ajustons les niveaux de couleur également pour les modes vidéos plus élevés...
//
if(VideoModeTypeScreen==VideoModeType_15)
if((VideoModeTypeScreen==VideoModeType_15) || (VideoModeTypeScreen==VideoModeType_24))
{
int m;
for (red_shift = 0, m = DisplayPixelFormat.dwRBitMask;
!(m & 1); red_shift++, m >>= 1);
red_scale=255/m;

for (green_shift = 0, m = DisplayPixelFormat.dwGBitMask;
!(m & 1); green_shift++, m >>= 1);
green_scale=255/m;

for (blue_shift = 0, m = DisplayPixelFormat.dwBBitMask;
!(m & 1); blue_shift++, m >>= 1);
blue_scale=255/m;
}

// Patch pour les captures d'écran prises en mode d'affichage 32 bit.
// Nous avons besoin du nombre d'octets par pixel, ce qui ne devrait pas être 4.
DWORD dwBytesPerPixel;

if ( VideoModeTypeScreen == VideoModeType_24 )
{
dwBytesPerPixel = DisplayPixelFormat.dwRGBBitCount >> 3;
}


// write 24 bit image

LockSurfaceAndGetBufferPointer();
unsigned char* BufferPtr=ScreenBuffer+BackBufferPitch*(h.WinInfo.Height-1);
for (i=h.WinInfo.Height-1; i>=0; --i)
{
int j;
if(VideoModeTypeScreen==VideoModeType_8)
{
for (j=0; j<h.WinInfo.Width; ++j) {
PutByte((BYTE)TestPalette[BufferPtr[j]*3+2]<<2,fp); //b
PutByte((BYTE)TestPalette[BufferPtr[j]*3+1]<<2,fp); //g
PutByte((BYTE)TestPalette[BufferPtr[j]*3]<<2,fp); //r
}
}
else if(VideoModeTypeScreen==VideoModeType_15)
{
short colour;
for (j=0; j<h.WinInfo.Width; ++j)
{
colour=*(short*)&BufferPtr[j*2];
PutByte((BYTE)(((colour & DisplayPixelFormat.dwBBitMask)>>blue_shift)*blue_scale),fp); //b
PutByte((BYTE)(((colour & DisplayPixelFormat.dwGBitMask)>>green_shift)*green_scale),fp); //g
PutByte((BYTE)(((colour & DisplayPixelFormat.dwRBitMask)>>red_shift)*red_scale),fp); //r
}
}
else if(VideoModeTypeScreen==VideoModeType_24)
{
// Nous avons besoin de couleurs plus élaborées ici...
/*
for (j=0; j<h.WinInfo.Width; ++j)
{
PutByte((BYTE)BufferPtr[j*3+2],fp); //b
PutByte((BYTE)BufferPtr[j*3+1],fp); //g
PutByte((BYTE)BufferPtr[j*3],fp); //r
}*/

// ... donc nous calculons chaque nouvelle valeur RVB
DWORD colour;

for ( j = 0; j < h.WinInfo.Width; ++j )
{
colour = *(DWORD*)&BufferPtr [j*dwBytesPerPixel];

PutByte ((BYTE)(((colour & DisplayPixelFormat.dwBBitMask)>>blue_shift)*blue_scale),fp); // b
PutByte ((BYTE)(((colour & DisplayPixelFormat.dwGBitMask)>>green_shift)*green_scale),fp); // g
PutByte ((BYTE)(((colour & DisplayPixelFormat.dwRBitMask)>>red_shift)*red_scale),fp); // r
}
}
// pad to 4 byte boundary
for (j=~(h.WinInfo.Width*3-1) & 3; j; --j) PutByte(0,fp);
BufferPtr-=BackBufferPitch;
}
UnlockSurface();

fclose(fp);
}
Et voilà ! Maintenant le truc devrait être ok, merci pyth pour le code !